Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架-包含的导航属性的选择条件_C#_Linq_Entity Framework_Navigation Properties - Fatal编程技术网

C# 实体框架-包含的导航属性的选择条件

C# 实体框架-包含的导航属性的选择条件,c#,linq,entity-framework,navigation-properties,C#,Linq,Entity Framework,Navigation Properties,假设我有这些简化的EF生成实体… public class PurchaseOrder { public int POID {get;set;} public int OrderID {get;set;} public int VendorID {get;set;} public IEnumerable<Order> Orders {get;set;} } public class Order { public int OrderI

假设我有这些简化的EF生成实体…

public class PurchaseOrder
{
     public int POID {get;set;}
     public int OrderID {get;set;}
     public int VendorID {get;set;}
     public IEnumerable<Order> Orders {get;set;}
}

public class Order
{
     public int OrderID {get;set;}
     public decimal Price {get;set;}
     public IEnumerable<Item> Items {get;set;}
}

public class Item
{
     public int OrderID {get; set;}
     public string SKU {get;set;}
     public int VendorID {get;set;}
     public Order Order {get;set;}
}
这就完成了它的工作,并收回相关的实体,但是,我只想包括其VendorID与PurchaseOrder实体的VendorID匹配的项目实体

对于传统的SQL,我只是将其包含在连接条件中,但EF在内部构建这些条件


我可以使用什么LINQ magic来告诉EF应用条件,而不必手动创建实体之间的连接?

您不能有选择地拉回与特定条件匹配的某些子实体。你能做的最好的事情就是自己手动过滤掉相关的订单

public class PurchaseOrder
{
     public int POID {get;set;}
     public int OrderID {get;set;}
     public int VendorID {get;set;}
     public IEnumerable<Order> Orders {get;set;}

     public IEnumerable<Order> MatchingOrders {
         get {
            return this.Orders.Where(o => o.VendorId == this.VendorId);
         }
     }
}
公共类采购订单
{
公共int点{get;set;}
公共int-OrderID{get;set;}
public int VendorID{get;set;}
公共IEnumerable命令{get;set;}
公共IEnumerable匹配顺序{
得到{
返回this.Orders.Where(o=>o.VendorId==this.VendorId);
}
}
}

你不能。EF不允许紧急加载的条件。您必须使用多个查询,如:

var pos = from p in context.PurchaseOrders.Include("Order")
          where ...
          select p;
var items = from i in context.Items
            join o in context.Orders on new { i.OrderId, i.VendorId} 
               equals new { o.OrderId, o.PurchaseOrder.VendorId }
            where // same condition for PurchaseOrders
            select i;
也可以在单个查询中使用投影:

var data = from o in context.Orders
           where ...
           select new
              {
                  Order = o,
                  PurchaseOrder = o.PurchaseOrder,
                  Items = o.Items.Where(i => i.VendorId == o.PurchaseOrder.VendorId)
              };

您可以在此处使用IQueryable扩展:

扩展动态构建匿名类型。这将用于@Ladislav Mrnka所述的投影

然后你可以这样做:

var query = query.SelectIncluding( new List<Expression<Func<T,object>>>>(){

//Example how to retrieve only the newest history entry
x => x.HistoryEntries.OrderByDescending(x => x.Timestamp).Take(1),

//Example how to order related entities
x => x.OtherEntities.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing),

//Example how to retrieve entities one level deeper
x => x.CollectionWithRelations.Select(x => x.EntityCollectionOnSecondLevel),

//Of course you can order or subquery the deeper level
//Here you should use SelectMany, to flatten the query
x => x.CollectionWithRelations.SelectMany(x => x.EntityCollectionOnSecondLevel.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing)),

});
var query=query.selectinclude(新列表>(){
//示例如何仅检索最新的历史记录条目
x=>x.HistoryEntries.OrderByDescending(x=>x.Timestamp).Take(1),
//如何对相关实体进行排序的示例
x=>x.OtherEntities.OrderBy(y=>y.Something)。然后by(y=>y.Something),
//示例如何检索更深一层的实体
x=>x.CollectionWithRelations.Select(x=>x.EntityCollectionsSecondLevel),
//当然,您可以对更深层次进行排序或子查询
//在这里,您应该使用SelectMany来展开查询
x=>x.CollectionWithRelations.SelectMany(x=>x.EntityCollectionsSecondLevel.OrderBy(y=>y.Something)。然后通过(y=>y.Something)),
});

我希望在未来将此视为一项功能增强。五年多了,但仍然一无所获。。。令人惊讶的是,对于EF可能拥有的最有用的功能之一来说,这并不坏
var query = query.SelectIncluding( new List<Expression<Func<T,object>>>>(){

//Example how to retrieve only the newest history entry
x => x.HistoryEntries.OrderByDescending(x => x.Timestamp).Take(1),

//Example how to order related entities
x => x.OtherEntities.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing),

//Example how to retrieve entities one level deeper
x => x.CollectionWithRelations.Select(x => x.EntityCollectionOnSecondLevel),

//Of course you can order or subquery the deeper level
//Here you should use SelectMany, to flatten the query
x => x.CollectionWithRelations.SelectMany(x => x.EntityCollectionOnSecondLevel.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing)),

});