[英]Filtering a graph of entity framework objects
我试图将EF返回的结果过滤掉只有那些相关的结果 - 在下面的例子中对一年中的那些(formattedYear)和ordertype(filtOrder)
我有一组简单的对象
人们1-M订单1-M订单
已经在Model.edmx中定义了这些关系
在SQL中我会做类似......
在ORDERS.PEOPLE_RECNO = PEOPLE.RECORD_NUMBER ORDERLINE ORDERLINE.ORDER_RECNO = ORDERS.RECORD_NUMBER ORDERLINE.SERVICE_YEAR=@formattedYear和ORDERS.ORDER_KEY=@filtOrder中选择*来自PEOPLE内部联接ORDERS ORDERS.PEOPLE_RECNO = PEOPLE.RECORD_NUMBER内部联接ORDERLINE
我尝试了几种方法......
var y = _entities.PEOPLE.Include("ORDERS").Where("it.ORDERS.ORDER_KEY=" + filtOrder.ToString()).Include("ORDERLINEs").Where("it.ORDERS.ORDERLINEs.SERVICE_YEAR='" + formattedYear + "'");
var x = (from hp in _entities.PEOPLE
join ho in _entities.ORDERS on hp.RECORD_NUMBER equals ho.PEOPLE_RECNO
join ol in _entities.ORDERLINEs on ho.RECORD_NUMBER equals ol.ORDERS_RECNO
where (formattedYear == ol.SERVICE_YEAR) && (ho.ORDER_KEY==filtOrder)
select hp
);
y失败,ORDER_KEY不是transient.collection的成员......而x返回正确的PEOPLE,但是他们已经附加了所有订单 - 而不仅仅是我追求的那些订单。
我想我错过了一些简单的东西?
想象一下,你有100个订单的人。 现在,您将这些订单过滤到10.最后,您选择拥有这些订单的人。 你猜怎么了? 这个人还有100个订单!
你要求的不是实体,因为你不需要整个实体。 您似乎想要的是来自实体的数据的子集。 所以预计:
var x = from hp in _entities.PEOPLE
let ho = hp.ORDERS.Where(o => o.ORDER_KEY == filtOrder
&& o.ORDERLINES.Any(ol => ol.SERVICE_YEAR == formattedYear))
where ho.Any()
select new
{
Id = hp.ID,
Name = hp.Name, // etc.
Orders = from o in ho
select new { // whatever
};
我不确定你的问题是什么,但以下内容可能会有所帮助。
在实体框架中,如果要加载对象图并过滤子对象,则可以首先对子对象进行查询并枚举它(即调用ToList()),以便将childern提取到内存中。
然后当你获取父对象(并且不使用.include)时,enitity框架将能够自己构建图形(但请注意,您可能必须先禁用延迟加载,否则将需要很长时间才能加载)。 这是一个例子(假设你的上下文是“db”):
db.ContextOptions.LazyLoadingEnabled = false;
var childQuery = (from o in db.orders.Take(10) select o).ToList();
var q = (from p in db.people select p).ToList();
现在您将发现每个人对象都有十个订单对象
编辑:当我编写示例代码时,我很匆忙,因此我还没有测试过,我可能会因为声称这样做而出错.Take(10)会为每个人对象带回10个订单,相反我相信当延迟加载被禁用时,Take(10)将仅返回十个整体订单(对于启用延迟加载的情况,我必须实际测试结果将是什么)并且为了每个订单返回10个订单人们反对你可能需要进行更广泛的过滤。
但这个想法很简单,你首先获取所有子对象,实体框架自己构造图形。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.