繁体   English   中英

过滤实体框架对象的图形

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM