我试图在Expression
LINQ
内使用Select
。这是我的代码的一个例子
Expression<Func<user, string>> expr = d => d.user.username;
Message.Select(b => new { name = b.user.Select(expr) });
消息的类型为IEnumerable
,在运行时我收到以下错误:
The exception message is ''System.Collections.Generic.List<W.Models.user>' does not contain a definition for 'Select'
我该如何解决这个问题?
答案 0 :(得分:5)
听起来你错过了代码文件顶部的using System.Linq;
。但请注意,List<T>
是LINQ到对象;失去Expression
:
Func<user, string> expr = d => d.user.username;
Message.Select(b => new { name = b.user.Select(expr) });
最后的想法;当关于System.Collections.Generic.List<W.Models.user>
的消息建议列表时,您的代码(b.User.Select
/ Message.Select
)会建议单个对象。这......令人困惑。
答案 1 :(得分:0)
请查看Why would you use Expression<Func<T>> rather than Func<T>?。
接受的答案描述Func<T>
是返回T
的方法的委托。 Expression<Func<T>>
实际上是一个描述,可以评估该委托的方式。例如,您可以compile an expression进入实际的委托:
Expression<Func<int, bool>> expr = i => i < 5;
Func<int, bool> deleg = expr.Compile();
Console.WriteLine("deleg(4) = {0}", deleg(4));
你甚至可以写:
Console.WriteLine("deleg(4) = {0}", expr.Compile()(4));
因此,如果你真的需要一个表达式,你需要将它编译成实际的委托,否则首先使用委托。
(顺便说一下:你的代码示例不会编译,因为Select
没有List<user>
方法接受表达式而且d => d.user.username
可能是错误的。自{{1} } d
应该是user
)。
然而linq to entities不支持委托调用。因此,您必须通过添加d => d.username
:
AsEnumerable()
使用linq实体访问数据,简单排序,过滤等。这样可以优化数据库的查询,但如果需要更多,则可以切换到linq到对象。
PS:lambda Expression<Func<user, string>> expr = d => d.username;
Func<user, string> func = expr.Compile();
var result = context.Message.AsEnumerable()
.Select(b => new { name = b.user.Select(func) });
被编译成一个委托。如果你明确地将它放入表达式d => d.username
中它将正常工作,因为现在这也可以编译成一个表达式,实体可以处理linq而无需调用委托。