2009-11-08 48 views
5

我們班LINQ到實體 - 在EntityCollection導航屬性搜索

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

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

我們給出IQueryable<Invoice>,我們沒有給出IQueryable<InvoicePosition>。我應該如何查找具有職位的發票,其中GroupName是「燃料」?

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

EntityFramework應該能夠將其轉換爲正確的sql查詢。

編輯

正如馬克·西曼寫的,我可以用:

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; 

有一個問題。當我使用這個過濾時,我輸了「OtherInclude」。我認爲這在使用EF時不是正確的過濾方式。我必須將其更改爲:

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

但是,我應該在哪裏寫?

編輯

改變包括( 「位置」),以包括( 「位置」)。

編輯

亞歷克斯·詹姆斯給了鏈接到尖端(http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx),這表明:

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

它似乎工作,不影響EF包括。

回答

5

大廈。如果你這樣做:

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

的包括丟失(見this tip),因爲EF失去所有包括如果查詢的形狀發生變化,例如,如果你做隱含從加入像在的SelectMany查詢,又名。

解決方法是編寫您的查詢,然後在最後應用Include。

事情是這樣的:

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

如果你這樣做實體框架實際上並在包括。

希望這有助於

亞歷

+0

感謝您的提示。最後添加Include是有問題的,因爲我使用了存儲庫模式,並且首先應用了包含。中間解決方案(使用Any())適合我。 – LukLed 2009-11-08 18:58:28

2

像這樣的東西應該工作:

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

但是,使用導航屬性Positions,默認情況下不加載(實體框架使用顯式加載)。然而,顯然,工作,如果invoices變量創建這樣的:關於商標的答案

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

如果編譯,也許它會工作:) – LukLed 2009-11-08 10:36:55

+0

Invoice.Positions是EntityCollection。它沒有GroupName屬性。它具有InvoicePosition的列表。 – LukLed 2009-11-08 10:39:29

+0

對不起,我誤解了問題中的代碼。我剛剛更新了答案。 – 2009-11-08 10:41:25