Linq to entities Left Join
Je veux atteindre les objectifs suivants dans Linq to entities:
Obtenir toutes les Demandes de renseignements qui n'ont pas d'Application ou l'Application dispose d'un statut != 4 (Terminé)
select e.*
from Enquiry enq
left outer join Application app
on enq.enquiryid = app.enquiryid
where app.Status <> 4 or app.enquiryid is null
Quelqu'un a fait cela avant, sans l'aide de DefaultIfEmpty(), ce qui n'est pas pris en charge par Linq to entities?
J'essaye d'ajouter un filtre pour un IQueryable requête comme ceci:
IQueryable<Enquiry> query = Context.EnquirySet;
query = (from e in query
where e.Applications.DefaultIfEmpty()
.Where(app=>app.Status != 4).Count() >= 1
select e);
Merci
Marque
- Pour ce que ça vaut DefaultIfEmpty est inclus dans les EF .NET 4.0.
- Merci Damien - l'avenir de l'EF améliorations .NET 4
Vous devez vous connecter pour publier un commentaire.
Ce faire:
Je ne trouve pas de LINQ traiter le problème de ce que serait une "jointure externe" dans SQL "dingo" à tous. La clé de la compréhension, il est à penser en termes d'un objet graphique avec les valeurs null propriétés plutôt que d'un tableau de jeu de résultats.
Tout() cartes EXISTE en SQL, il est donc loin plus efficace que la fonction Count() dans certains cas.
En EF 4.0+, à GAUCHE de la syntaxe de JOINTURE est un peu différente et présente un fou caprice:
Si vous capturez l'exécution de cette requête dans SQL Server Profiler, vous verrez qu'il n'est en effet effectuer une JOINTURE EXTERNE GAUCHE. TOUTEFOIS, si vous avez plusieurs LEFT JOIN ("Rejoindre le Groupe") des clauses de votre Linq-to-Entité de la requête, j'ai trouvé que l'auto-clause de jointure PEUT effectivement exécuter comme dans INNER JOIN - MÊME SI LA SYNTAXE ci-DESSUS!
La résolution? Comme un fou et, selon MME, mal à ce qu'il paraît, j'ai résolu ce problème en changeant l'ordre des clauses join. Si l'auto-référencement GAUCHE de la clause de JOINTURE a été le 1er Linq Groupe de Rejoindre, le générateur de profils SQL signalé une JOINTURE INTERNE. Si l'auto-référencement GAUCHE de la clause de JOINTURE a été le DERNIER Linq Groupe de Rejoindre, le générateur de profils SQL signalé un LEFT JOIN.
Merci les gars pour votre aide. Je suis pour cette option à la fin, mais vos solutions ont permis d'élargir mes connaissances.
En raison de Linq dingo (la lecture de " non-standard) de manipulation des outers, vous devez utiliser DefaultIfEmpty().
Ce que vous allez faire est de lancer votre Linq-to-Entités requête dans les deux IEnumerables, puis à GAUCHE se Joindre à eux à l'aide de DefaultIfEmpty(). Il peut ressembler à quelque chose comme:
Juste parce que vous ne pouvez pas le faire avec Linq-to-Entités ne signifie pas que vous ne pouvez pas le faire avec les premières Linq.
(Note: avant que quelqu'un downvotes moi ... oui, je sais qu'il y a plus élégante des façons de le faire. Je suis juste en train de le rendre compréhensible. C'est le concept qui est important, non?)
Une autre chose à considérer si vous directement référence à des propriétés dans votre clause where d'une gauche rejoint le groupe (à l'aide de la dans la syntaxe) sans vérifier null, Entity Framework sera toujours convertir votre GAUCHE, REJOINDRE en une JOINTURE INTERNE.
Pour éviter cela, le filtre sur les "à partir de x dans leftJoinedExtent" une partie de votre requête comme ceci:
ChildID dans l'anonyme de type pour un type nullable et la requête cela génère sera un LEFT JOIN.