【问题标题】:Custom OrderBy extension method fails while projecting anonymous type投影匿名类型时自定义 OrderBy 扩展方法失败
【发布时间】:2013-07-21 16:29:24
【问题描述】:

关于the answer proposed in this post,谁能解释一下为什么LINQPad不会为此生成任何SQL?

var query = Products.Select(p => new 
{ 
    Orders = p.Orders.OrderByWithDirection(x => x.PurchaseDate, true) 
});

例外情况如下:

NotSupportedException:方法 'System.Linq.IOrderedEnumerable1[LINQPad.User.Order] OrderByWithDirection[Phase,String](System.Collections.Generic.IEnumerable1[LINQ‌​Pad.User.Order], System.Func`2[LINQPad.User.Order,System.String], Boolean)' 没有支持的翻译到 SQL。

【问题讨论】:

  • 那么错误是什么?如果我们不知道发生了什么,我们真的无能为力。
  • 可能是因为延迟执行?如果您发出var results = query.ToList(),是否会生成任何 SQL?
  • @JonSkeet: 异常如下: NotSupportedException: Method 'System.Linq.IOrderedEnumerable1[LINQPad.User.Order] OrderByWithDirection[Phase,String](System.Collections.Generic.IEnumerable1[LINQPad.User.Order], System.Func`2[LINQPad.User.Order, System.String], Boolean)' 不支持 SQL 转换。
  • @Douglas:不会生成 SQL。

标签: c# linq linqpad


【解决方案1】:

问题不在于它是匿名类型的一部分 - 问题在于您实际上并没有直接调用OrderByWithDirection...相反,您在投影中构建了一个表达式树并且该表达式树包含对OrderByWithDirection 的引用,这是 LINQ to SQL(或 EF 或其他)不知道的。

除了表达式树访问者通过表达式树并根据第二个参数将调用替换为 OrderByOrderByDescending 之外,我想不出任何好的解决方法 - 这必须是一个常数,当然。即使这也绝非易事。

说实话,我可能会采用低技术含量的方法 - 尽可能多地保持查询相同,然后在最后有条件地调用 OrderByOrderByDescending

var mainQuery = ...; // Stuff which is in common

var query = direction
    ? mainQuery.Select(p => new { Orders = p.Orders.OrderBy(x => x.PurchaseDate) })
    : mainQuery.Select(p => new { Orders = p.Orders.OrderByDescending(x => x.PurchaseDate) });

顺便说一句,我假设您的真实查询在匿名类型中有更多属性?很少有充分的理由来创建具有单个属性的匿名类型。

【讨论】:

  • 谢谢。如果有比重建表达式树更简单的修复方法,那就太好了……
  • 我已经在使用您提出的低技术方法,但是由于查询量很大,代码变得越来越可怕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
相关资源
最近更新 更多