此问题已在此处有答案:
Dynamic LINQ OrderBy on IEnumerable / IQueryable(24回答)
去年关闭。
我想通过字符串参数生成表达式,一些代码如下:
private Expression<Func<Task, T>> Generate(string orderby)
{
switch (orderby)
{
case "Time":
return t => t.Time;
case "Money":
return t => t.RewardMoney;
default:
return t => t.Id;
}
}
然后称之为:
_context.Items.OrderBy(Generate("Money"));
但它不能编译!我把T改为object。
private Expression<Func<Task, object>> Generate(string orderby)
然后它可以编译,但它不工作。
System.NotSupportedException:无法将类型“System.Int32”强制转换为类型“System. Object”。LINQ to Entities仅支持转换EDM基元或枚举类型。
6条答案
按热度按时间b4qexyjb1#
使用reflection和expression-trees可以提供参数然后调用
OrderBy
函数,而不是返回Expression<Func<Task, T>>
然后调用OrderBy
。请注意,
OrderBy
是一个扩展方法,并且已经在System.Linq.Enumarable
和System.Linq.Queryable
类中实现。第一个用于linq-to-objects,第二个用于linq-to-entities。entity-framework需要查询的表达式树,以便将其转换为SQL命令。所以我们使用Queryable
实现。它可以通过扩展方法来完成(解释作为注解添加):
现在可以像调用
OrderBy
的其他重载一样调用它。例如:
翻译过来就是:
这种方法可用于定义
OrderBy
和OrderByDescending
方法的所有重载,使其具有string
属性选择器。dy1byipe2#
对于那些正在寻找EF Core解决方案的人:
Microsoft.EntityFrameworkCore.EF
中有一组函数可用于动态访问和查询编译。您可以使用EF.Property
方法按属性名称甚至shadow属性对可查询对象进行排序。示例:来源:教程:了解高级方案-使用EF Core的ASP.NET MVC
mm5n2pyu3#
您可以尝试将
Generate
方法转换为泛型方法:因此,如果调用此方法,则需要指定要排序的属性的类型:
现在请记住,
TResult
只能是原始类型或枚举类型。p1tboqfb4#
我参考了CodePlex中旧的System.Linq.Dynamic codebase,并从实现和调用的Angular 创建了一个非常简单的版本。当然,它是
IQueryable<T>
上的一个扩展方法以下是如何使用它的示例,针对Entity Framework Core 3进行了测试:
mxg2im7a5#
使用泛型方法。因为lambda表达式只能被赋值给强类型的委托或表达式,所以我们必须使用一个相应的临时变量。然后我们可以将这个temp赋值给一个类型为
object
的变量。最后,我们可以通过转换为结果类型来返回结果。0ve6wy6x6#