Linq to entities - 在EntityCollection導航屬性中搜索

entity-framework linq linq-to-entities

我們有課

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

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

我們獲得了IQueryable<Invoice> ,我們沒有給出IQueryable<InvoicePosition> 。我應該如何找到有位置的發票,其中GroupName是'Fuel'?

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

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

編輯

正如Mark Seemann所寫,我可以使用:

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(???);

但是我應該在哪裡寫?

編輯

已將包含(“職位”)更改為包含(“職位”)。

編輯

Alex James給出了提示鏈接( 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包括。

一般承認的答案

以Marks答案為基礎。如果你這樣做:

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

包含丟失(請參閱此提示 ),因為如果查詢的形狀發生更改,EF會丟失所有包含,例如,如果您執行類似於SelectMany查詢的隱式聯接,也就是來自from。

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

像這樣的東西:

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

如果您這樣做,實體框架實際上執行包含。

希望這可以幫助

亞歷克斯


熱門答案

這樣的事情應該有效:

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

但是,它使用導航屬性Positions ,默認情況下不會加載(Entity Framework使用顯式加載)。但是,如果invoices變量是這樣創建的,它將起作用:

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


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因