Linq to entity - recherche dans les propriétés de navigation EntityCollection

entity-framework linq linq-to-entities

Question

Nous avons des cours

public Invoice: EntityObject
{
    public EntityCollection<InvoicePosition> Positions { get {...}; set{...}; }
    ...
}

public InvoicePosition: EntityObject
{
    public string GroupName { get {...}; set{...}; }
}

On nous donne IQueryable<Invoice> , on ne nous donne pas IQueryable<InvoicePosition> . Comment trouver des factures comportant des positions, dans lesquelles GroupName est "Carburant"?

IQueryable<Invoice> invoices = InvoiceRepository.List();
IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices
    where ?
    select i

EntityFramework devrait pouvoir le traduire en requête SQL appropriée.

MODIFIER

Comme Mark Seemann a écrit, je peux utiliser:

IQueryable<Invoice> invoices = InvoiceRepository.List().Include("Positions").Include("OtherInclude");
IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices
    from p in i.Positions
    where p.GroupName = 'Fuel'
    select i;

Il ya un problème. Lorsque j'utilise ce filtrage, je perds "OtherInclude". Je pense que ce n'est pas la bonne façon de filtrer lors de l'utilisation de EF. Je vais devoir le changer pour:

IQueryable<Invoice> invoices = InvoiceRepository.List().Include("Positions").Include("OtherInclude");
IQueryable<Invoice> invoicesThatHaveFuelPositions = invoices.Where(???);

Mais que devrais-je écrire dans Où?

MODIFIER

Inclure ("Position") en Inclure ("Positions").

MODIFIER

Alex James a donné un lien vers le conseil ( http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx ), qui suggère:

IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices
    where i.Positions.Any(p => p.GroupName == 'Fuel')
    select i;

Cela semble fonctionner et n'influence pas les EF inclus.

Réponse acceptée

S'appuyant sur les marques répondent. Si tu fais ça:

var q = from i in invoices.Include("something")
        from p in i.Positions
        where p.GroupName == "Fuel"
        select i;

L'inclusion est perdue (voir cette astuce ) car l'EF perd toutes les inclusions si la forme de la requête change, par exemple si vous effectuez des jointures implicites comme dans une requête SelectMany, à partir de.

La solution consiste à écrire votre requête, puis à appliquer à la fin l'inclusion.

Quelque chose comme ça:

var q = ((from i in invoices
        from p in i.Positions
        where p.GroupName == "Fuel"
        select i) as ObjectQuery<Invoice>).Include("something");

Si vous faites cela, Entity Framework fait l'inclusion.

J'espère que cela t'aides

Alex


Réponse populaire

Quelque chose comme ça devrait marcher:

var q = from i in invoices
        from p in i.Positions
        where p.GroupName == "Fuel"
        select i;

Cependant, cela utilise la propriété de navigation Positions , qui par défaut n'est pas chargée (Entity Framework utilise un chargement explicite). Cela fonctionnera cependant si la variable invoices été créée comme ceci:

var invoices = from i in myObjectContext.Invoices.Include("Positions")
               select i;


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow