EF core Linq groupby and having sum count - could not be translated and will be evaluated locally

孤街浪徒 提交于 2020-01-04 09:08:28

问题


Following .net core EF core, Linq cannot be translated and will be evaluated locally. Can you please give me an advise?

var temp1= (from so in context.OrderShippingOrders
            group so by so.OrderId into g
            where g.Count(x=> x.IsSent == true ) == g.Count()
            select new {
                        g.Key
                       }
           );

            query = (from o in context.Orders
                     join s in temp1
                     on o.Id equals s.Key
                     select o
                     );

The LINQ expression 'join AnonymousObject _o in {from Order o in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[ECommerce.API.Models.Order]) where ([o].ShopId == __queryObj_ShopId_Value_0) join <>f__AnonymousType181 s in {from IGrouping2 g in {from OrderShippingOrder so in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[ECommerce.API.Models.OrderShippingOrder]) orderby [so].OrderId asc, [so].OrderId asc select [so] => GroupBy([so].OrderId, [so])} where ({from OrderShippingOrder x in [g] where ([x].IsSent == True) select [x] => Count()} == {[g] => Count()}) select new <>f__AnonymousType181(Key = [g].Key)} on [o].Id equals [s].Key orderby EF.Property(?[o]?, "Id") asc select new AnonymousObject(new [] {Convert(EF.Property(?[o]?, "Id"), Object)}) => Skip(__p_1) => Take(__p_2) => Distinct()} on Property([o.OrderDetails], "OrderId") equals Convert([_o].GetValue(0), Nullable1)' could not be translated and will be evaluated locally.


回答1:


If possible, upgrade to EF Core 2.1 (or 2.2) in order to get improved LINQ GroupBy translation.

Before version 2.1, in EF Core the GroupBy LINQ operator would always be evaluated in memory. We now support translating it to the SQL GROUP BY clause in most common cases.

There is nothing you can do in previous EF Core versions.

After upgrading, in order to get SQL transation, the GroupBy query must be modified to use intermediate projection and conditional Sum instead of conditional Count like this:

var temp1 = (from so in context.OrderShippingOrders
             group new { SendCount = so.IsSent ? 1 : 0 } by so.OrderId into g
             where g.Sum(x => x.SendCount) == g.Count()
             select new
             {
                 g.Key
             }
);

(unfortunately the more natual group so and g.Sum(x => x.IsSent ? 1 : 0) does not translate, that's why we need the group new { SendCount = so.IsSent ? 1 : 0 } and g.Sum(x => x.SendCount))


P.S. In case you have collection navigation property from Order to OrderShippingOrder (something like public ICollection<OrderShippingOrder> Shipping { get; set; }), then you can avoid all these GroupBy complications and use simply:

var query = context.Orders
    .Where(o => o.Shipping.Count(so => so.IsSent) == o.Shipping.Count());


来源:https://stackoverflow.com/questions/53730334/ef-core-linq-groupby-and-having-sum-count-could-not-be-translated-and-will-be

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!