Linq到实体-在EntityCollection导航属性中搜索

Linq到实体-在EntityCollection导航属性中搜索,linq,entity-framework,linq-to-entities,Linq,Entity Framework,Linq To Entities,我们有课 public Invoice: EntityObject { public EntityCollection<InvoicePosition> Positions { get {...}; set{...}; } ... } public InvoicePosition: EntityObject { public string GroupName { get {...}; set{...}; } } 公共发票:EntityObject { 公共

我们有课

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

public InvoicePosition: EntityObject
{
    public string GroupName { get {...}; set{...}; }
}
公共发票:EntityObject { 公共EntityCollection位置{get{…};set{…};} ... } 公共发票位置:EntityObject { 公共字符串组名{get{…};set{…};} } 我们被赋予了
IQueryable
,我们没有被赋予
IQueryable
。我应该如何找到有位置的发票,其中GroupName是“Fuel”

IQueryable<Invoice> invoices = InvoiceRepository.List();
IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices
    where ?
    select i
IQueryable invoices=InvoiceRepository.List();
IQueryable Invoicest haveFuelPositions=
发票中的i
哪里
选择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;
IQueryable invoices=InvoiceRepository.List().Include(“职位”).Include(“其他包括”);
IQueryable Invoicest haveFuelPositions=
发票中的i
从i.位置的p开始
其中p.GroupName='Fuel'
选择i;
有一个问题。使用此筛选时,我将丢失“OtherInclude”。我认为在使用EF时,这不是正确的过滤方式。我必须将其更改为:

IQueryable<Invoice> invoices = InvoiceRepository.List().Include("Positions").Include("OtherInclude");
IQueryable<Invoice> invoicesThatHaveFuelPositions = invoices.Where(???);
IQueryable invoices=InvoiceRepository.List().Include(“职位”).Include(“其他包括”);
IQueryable Invoicest haveFuelPositions=发票,其中(???);
但是我应该在哪里写什么呢

编辑

将包含(“位置”)更改为包含(“位置”)

编辑

Alex James提供了提示()的链接,提示:

IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices
    where i.Positions.Any(p => p.GroupName == 'Fuel')
    select i;
IQueryable Invoicest haveFuelPositions=
发票中的i
其中i.Positions.Any(p=>p.GroupName=='Fuel')
选择i;

它似乎起作用,但不影响EF。类似的东西应该起作用:

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;
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.Include("something")
        from p in i.Positions
        where p.GroupName == "Fuel"
        select i;
include会丢失(请参阅),因为如果查询的形状发生更改,例如如果您在SelectMany查询(也称为from)中执行隐式连接,EF会丢失所有include

解决方法是编写查询,然后在最后应用Include

大概是这样的:

var invoices = from i in myObjectContext.Invoices.Include("Positions")
               select i;
var q = ((from i in invoices
        from p in i.Positions
        where p.GroupName == "Fuel"
        select i) as ObjectQuery<Invoice>).Include("something");
var q=((来自发票中的i)
从i.位置的p开始
其中p.GroupName==“燃料”
选择i)作为ObjectQuery)。包括(“某物”);
如果您这样做,实体框架实际上会包含

希望这有帮助


Alex

Invoice.Positions是实体集合。它没有GroupName属性。它有发票位置列表。对不起,我误读了问题中的代码。我刚刚更新了答案。谢谢,现在它已经编译好了,但与EF不兼容。从存储库中获取时,我有Include(“位置”),但我也有其他Include,它们在该操作中丢失。您应该能够将调用链接到一起,并且在查询之后,它们都应该在对象上填充。我需要更多的信息来告诉你为什么其他包含丢失。什么信息?我在Profiler中看到EF构造了其他查询,但它不包含已定义的包含。感谢这篇技巧。最后添加Include是有问题的,因为我使用存储库模式,并且首先应用Include。中间的解决方案(使用Any())适合我。