2011-09-21 5 views
2

Scénario: J'ai une table de profils d'utilisateurs et une table de collègues. La table des collègues dispose d'un enregistrement pour tous les autres utilisateurs qu'un profil utilisateur suit. Dans cette requête, j'attrape toutes les personnes qui suivent l'utilisateur actuellement connecté (en récupérant leurs ID d'enregistrement dans la table des collègues et en rejoignant la table de profil utilisateur pour obtenir leurs détails). Ensuite, je rejoins la table Collègues pour voir si l'utilisateur connecté suit cet utilisateur.DefaultIfEmpty() Causer "System.NotSupportedException: LINQ to Entities ne reconnaît pas la méthode« System.Collections.Generic.IEnumerable"

Problème: Je crois comprendre que la meilleure façon de faire un LEFT JOIN (à la recherche du dossier collègue dans lequel l'utilisateur suit de nouveau collègue) est d'ajouter « DefaultIfEmpty() » à cette jointure. Quand j'ajoute .DefaultIFEmpty() à cette jointure, je reçois le message d'erreur suivant:

System.NotSupportedException: LINQ to Entities ne reconnaît pas la méthode 'System.Collections.Generic.IEnumerable'

Si je supprime le ".DefaultIFEmpty()" de cette jointure, cela fonctionne. Cependant, il l'exécute en tant que JOIN régulier, en omettant les enregistrements où l'utilisateur ne suit pas le collègue.

code: Voici le code que je utilise:

var results = (from a1 in db.Colleague 
join b1 in db.UserProfile on new {ColleagueId = a1.ColleagueId} equals 
    new {ColleagueId = b1.RecordId} 
join d1 in db.UserProfile on new {RecordId = a1.OwnerId} equals 
    new {RecordId = d1.RecordId} 
join c1 in db.Colleague 
    on new {OwnerId = b1.RecordId, Ignored = false, ColleagueId = a1.OwnerId} 
    equals new {c1.OwnerId, c1.Ignored, c1.ColleagueId} into c1Join 
from c1 in c1Join.DefaultIfEmpty() // This is the .DefaultIfEmpty() breaking the query 
where 
    b1.AccountName == userName && 
    a1.Ignored == false 
orderby 
    b1.LastName 
select new 
{ 
    RecordId = (System.Int64?) d1.RecordId, 
    d1.AccountName, 
    d1.PreferredName, 
    d1.FirstName, 
    d1.LastName, 
    d1.PictureUrl, 
    d1.PublicUrl, 
    IsFollowing = c1.OwnerId < 1 ? 0 : 1 
}); 
foreach (var result in results) // This is what throws the error 
{ 
    // Do stuff 
} 

Toutes les idées?

+1

Je commencerais par refactoring pour rendre le code plus lisible. Vous n'avez pas besoin de tout faire en une seule fois, vous pouvez avoir des requêtes intermédiaires et il sera toujours envoyé au serveur SQL en une seule requête. Vous n'avez pas besoin de créer tous ces objets anonymes, vous pouvez simplement faire a1.ColeagueID == b1.RecordId par exemple. Une fois cela fait, il sera plus facile pour les gens de déterminer ce qui ne va pas. – ForbesLindesay

Répondre

2

Le fournisseur SQL pour Entity Framework dans la version 3.5 de .NET Framework ne prend pas en charge DefaultIfEmpty(). Désolé, mais n'a pas trouvé de meilleure référence que cet article: http://smehrozalam.wordpress.com/2009/06/10/c-left-outer-joins-with-linq/

Vous pouvez essayer directement LINQ-to-SQL plutôt qu'ADO.NET Entity Framework. Je crois que cela fonctionne dans LINQ-to-SQL. J'ai vérifié dans le passé que les jointures gauche fonctionnent en 3.5 via LinqPad.

+0

D'après votre suggestion, j'ai pu faire ce travail en utilisant LINQ to SQL à la place, merci. –

+0

Quelqu'un peut-il fournir un exemple de la syntaxe linq to sql? – Bruno

1

DefaultIfEmpty est pris en charge uniquement dans EFv4 +. La première version d'EF ne prend pas en charge DefaultInEmpty.

2

Il semble que vous deviez créer une valeur par défaut pour passer à DefaultIfEmpty(), car DefaultIsEmpty() prend un paramètre.

DefaultIfEmpty() on MSDN

Questions connexes