Linq zu Entitäten - In EntityCollection-Navigationseigenschaften suchen

entity-framework linq linq-to-entities

Frage

Wir haben Unterricht

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

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

Wir erhalten IQueryable<Invoice> , wir erhalten nicht IQueryable<InvoicePosition> . Wie finde ich Rechnungen mit Positionen, bei denen GroupName "Kraftstoff" ist?

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

EntityFramework sollte es in die richtige SQL-Abfrage übersetzen können.

BEARBEITEN

Wie Mark Seemann schrieb, kann ich Folgendes verwenden:

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;

Es gibt ein Problem. Wenn ich diese Filterung verwende, verliere ich "OtherInclude". Ich denke, dass dies nicht die richtige Art der Filterung ist, wenn EF verwendet wird. Ich muss es ändern in:

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

Aber was soll ich in Wo schreiben?

BEARBEITEN

Include ("Position") in Include ("Positionen") geändert.

BEARBEITEN

Alex James gab einen Link zu dem Tipp ( http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx ), der folgende Vorschläge enthält:

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

Es scheint zu funktionieren und beeinflusst EF nicht.

Akzeptierte Antwort

Antwort auf die Marke. Wenn du das tust:

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

Das Include geht verloren (siehe diesen Tipp ), da die EF alle Include-Elemente verliert, wenn sich die Form der Abfrage ändert, beispielsweise wenn Sie implizite Verknüpfungen wie in einer SelectMany-Abfrage (auch von) ausführen.

Die Problemumgehung besteht darin, Ihre Abfrage zu schreiben und am Ende den Include anzuwenden.

Etwas wie das:

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

Wenn Sie dies tun, führt das Entity Framework das Include tatsächlich aus.

Hoffe das hilft

Alex


Beliebte Antwort

So etwas sollte funktionieren:

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

Dabei wird jedoch die Navigationseigenschaft Positions , die standardmäßig nicht geladen wird (Entity Framework verwendet explizites Laden). Es funktioniert jedoch, wenn die invoices Variable folgendermaßen erstellt wurde:

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


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum