2009-11-08 16 views
5

Mamy zajęciaLINQ do podmiotów - w poszukiwaniu właściwości nawigacyjnych EntityCollection

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

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

Jesteśmy podane IQueryable<Invoice>, nie podano IQueryable<InvoicePosition>. Jak znaleźć faktury, które mają pozycje, gdzie GroupName to "Fuel"?

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

EntityFramework powinien móc przełożyć je do właściwego zapytania SQL.

EDIT

Jak napisał Mark Seemann, mogę użyć:

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; 

Jest problem. Kiedy używam tego filtrowania, tracę "OtherInclude". Myślę, że nie jest to właściwy sposób filtrowania podczas używania EF. Będę musiał go zmienić na:

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

Ale co mam pisać Gdzie?

EDIT

Zmieniono include ("Position"), które obejmują ("Pozycje").

EDIT

Alex James dał link do końcówki (http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx), co sugeruje:

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

Wydaje się pracować i nie wpływa EF obejmuje.

Odpowiedz

5

Opierając się na znakach odpowiedź. Jeśli tak to:

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

include zostaną utracone (patrz this tip), ponieważ EF traci wszystko obejmuje, jeżeli kształt zmian zapytań, na przykład, jeśli nie ukryte przyłącza się jak w zapytaniu SelectMany, aka z od .

Rozwiązaniem jest zapisanie zapytania, a na końcu zastosowanie opcji Uwzględnij.

coś takiego:

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

Jeśli zrobisz to Entity Framework faktycznie robi to.

Nadzieja to pomaga

Alex

+0

Dzięki za tę wskazówkę. Dodanie opcji Uwzględnij na końcu jest problematyczne, ponieważ używam wzorca repozytorium, a uwzględnienia są stosowane jako pierwsze. Środkowe rozwiązanie (używając Any()) pasuje do mnie. – LukLed

2

Coś jak to powinno działać:

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

jednak, że wykorzystuje właściwość nawigacji Positions, która domyślnie nie jest załadowany (Entity Framework używa wyraźny załadunku). To będzie jednak pracować, jeśli zmienna invoices został stworzony tak:

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

Jeśli jest kompilowany, może to działa :) – LukLed

+0

Invoice.Positions jest EntityCollection. Nie ma właściwości GroupName. Ma listę InvoicePosition. – LukLed

+0

Przepraszamy, błędnie przeczytałem kod w pytaniu. Właśnie zaktualizowałem odpowiedź. –

Powiązane problemy