2009-11-08 46 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