J'ai le SQL ci-dessous qui fonctionne très bien:Besoin d'aide Translating SQL Server UNION syntaxe LINQ
SELECT Message, CreateDate, AccountId, AlertTypeId
FROM dbo.Alerts
UNION
SELECT TOP (100) PERCENT Status, CreateDate, AccountId,
(SELECT 10 AS Expr1) AS AlertTypeId
FROM dbo.StatusUpdates
WHERE AccountId = PassedInParameter
ORDER BY CreateDate DESC
Je suis en train de le convertir en LINQ, qui ne fonctionne pas très bien :) De toute évidence, il Il y a beaucoup de mal ici - c'est juste un début difficile. Il ne tient pas compte de la colonne de température au-dessus ou la condition order by
et l'ambiguïté des génériques/type de retour est ma tentative de comprendre les deux types de retour différents:
public List<T> GetSomething<T>(Int32 accountId)
{
List<T> result;
using (DataContext dc = _conn.GetContext())
{
IEnumerable<Alert> alerts = (from a in dc.Alerts
where a.AccountId == accountId
select a);
IEnumerable<StatusUpdate> updates = (from s in dc.StatusUpdates
where s.AccountId == accountId
select s);
IEnumerable<T> obj = alerts.Union(updates);
result = obj.ToList();
}
return result;
}
Les problèmes que je rencontrais sont:
1) J'ai affaire à deux types différents (Alertes et StatusUpdate) dans mes sélections et Je ne suis pas sûr de savoir comment les combiner (ou quel type retourner). Je devine que cela pourrait être résolu avec des génériques?
2) Dans mon SQL, j'ai ce code: (SELECT 10 AS Expr1) AS AlertTypeId
qui ajoute la valeur dix à la colonne temp AlertTypeId (permettant à l'union de la faire correspondre à la vraie colonne AlertTypeId d'Alert). Comment les colonnes temporaires sont-elles accomplies dans LINQ/comment faire?
Merci pour votre aide.
EDIT --------------------------------- EDIT ---------- -------------------------------- EDIT
OK, je suis un peu plus loin. Voici ce que j'ai actuellement. Vous remarquerez que j'ai ajouté une certaine logique pour retourner les mises à jour pour les relations d'amis. J'ai également fait cela une méthode générique de type IList
étant donné que les alertes et les mises à jour doivent être génériques pour être d'accord. Je passe dans StatusUpdate dans la méthode d'appel (plus bas ci-dessous).
public IList GetUpdatesByAccountId<T>(Int32 accountId)
{
List<Friend> friends = _friendRepository.GetFriendsByAccountId(accountId);
using (DataContext dc = _conn.GetContext())
{
// Get all the account ids related to this user
var friendAccountIds =
friends.Select(friend => friend.MyFriendsAccountId).Distinct();
friendAccountIds = friendAccountIds.Concat(new[] { accountId });
var updates =
dc.StatusUpdates.Where(s => s.AccountId.HasValue && friendAccountIds.Contains(s.AccountId.Value)).Select(
s => new { Alert = (Alert)null, StatusUpdate = s});
var alerts =
dc.Alerts.Where(a => a.AccountId == accountId).Select(
a => new {Alert = a, StatusUpdate = (StatusUpdate) null});
var obj = updates.Union(alerts).Take(100);
return obj.OrderByDescending(su => su.StatusUpdate.CreateDate).ToList();
}
}
Et, la méthode d'appel:
protected void LoadStatus()
{
repStatusUpdates.DataSource = _statusRepository
.GetUpdatesByAccountId<StatusUpdate>(_userSession.CurrentUser.AccountId);
repStatusUpdates.DataBind();
}
et voici les interfaces aux référentiels que je utilise pour accéder à mon alerte et tables StatusUpdate via LINQ:
public interface IAlertRepository
{
List<Alert> GetAlertsByAccountId(Int32 accountId);
void SaveAlert(Alert alert);
void DeleteAlert(Alert alert);
}
public interface IStatusUpdateRepository
{
StatusUpdate GetStatusUpdateById(Int32 statusUpdateId);
List<StatusUpdate> GetStatusUpdatesByAccountId(Int32 accountId);
List<StatusUpdate> GetFriendStatusUpdatesByAccountId(Int32 accountId, Boolean addPassedInAccount);
void SaveStatusUpdate(StatusUpdate statusUpdate);
List<StatusUpdate> GetTopNStatusUpdatesByAccountId(Int32 accountId, Int32 number);
List<StatusUpdate> GetTopNFriendStatusUpdatesByAccountId(Int32 accountId, Int32 number, Boolean addPassedInAccount);
}
Problèmes actuels :
1) Lorsque je compile ce code, j'obtiens cette erreur étrange:La seule lecture que je peux trouver sur elle est this link bien qu'il n'y ait pas une solution claire là (au moins que je peux dire). Cependant, si le code LINQ ci-dessus ne vous convient pas, peut-être que ce que vous suggérez fera disparaître cette erreur.
2) Le code ci-dessus est toujours pas rendre compte de cette ligne de SQL d'origine:
(SELECT 10 AS Expr1) AS AlertTypeId
mais cela est mineur.
Merci encore pour l'aide.
Ce message d'erreur bizarre signifie probablement que votre requête LinqToSQL était trop compliquée pour LinqToSQL, même si compliquée que leurs tests ne tenaient pas compte de l'écriture de ce code. – erikkallen
Je ne vois pas l'intérêt de faire de cette méthode une méthode générique. De plus, vous ne voulez pas faire l'union Take after you parce que ce n'est pas ce que vous faites dans la requête SQL. – Merritt
Pas le plus grand fan de la création d'une liste de paires StatusUpdate/Alert où l'un d'eux est toujours nul. L'utilisation d'un type anonynonmique va ici limiter son utilité en dehors de la liaison de données et nécessitera potentiellement une réflexion pour trouver les valeurs de propriété. – Merritt