我们有课程
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(???);
但是我应该在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包括。
答案 0 :(得分:5)
以Marks答案为基础。如果你这样做:
var q = from i in invoices.Include("something")
from p in i.Positions
where p.GroupName == "Fuel"
select i;
包含丢失(请参阅this tip),因为如果查询的形状发生变化,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");
如果您这样做,实体框架实际上会执行包含。
希望这有帮助
亚历
答案 1 :(得分: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;