Linq lambda 实体,不包含定义
Posted
技术标签:
【中文标题】Linq lambda 实体,不包含定义【英文标题】:Linq lambda entities , does not contain definition 【发布时间】:2013-07-09 08:06:45 【问题描述】:我这里有这个查询代码:
//Get all records based on ActivityID and TaskID.
public IList<Model.questionhint> GetRecords1(int listTask, int listActivity)
IList<Model.questionhint> lstRecords = context.questionhints.ToList();
return lstRecords.GroupBy(x => new x.QuestionNo, x.ActivityID, x.TaskID ).Where(a => a.TaskID == listTask && a.ActivityID == listActivity).ToList();
错误在于.Where
语句,它说不包含ActivityID
和TaskID
的定义。
完全错误:
“System.Linq.IGrouping”不包含“ActivityID”的定义,并且找不到接受“System.Linq.IGrouping”类型的第一个参数的扩展方法“ActivityID”(您是否缺少 using 指令或程序集参考?)
我的查询语句很弱,基本上我想从数据库中检索活动 id = something 和 task id = something 的记录,并按 questionNo、activityId 和 Task ID 对它们进行分组。
【问题讨论】:
顺便说一句;如果context
这里是一个提供程序,如 LINQ-to-SQL、EF 等 - 那么IList<Model.questionhint> lstRecords = context.questionhints.ToList();
是一个真的 坏主意 - 这会迫使它加载整个表,在 where
等之前 - 并切换到 LINQ-to-Objects。我已经编辑了我的答案以展示如何避免这种情况
【参考方案1】:
这里最简单的解决方法是:在分组之前过滤(哪里);这也将减少分组必须做的工作:
return context.questionhints
.Where(a => a.TaskID == listTask && a.ActivityID == listActivity)
.GroupBy(x => new x.QuestionNo, x.ActivityID, x.TaskID )
.ToList();
如前所述,它在您的原始代码中不起作用的原因是,GroupBy
返回一个 组 序列 - 每个组都有一个 .Key
(您的匿名类型)并且本身就是该组中项的IEnumerable<T>
序列。
但是!您的方法声称返回IList<Model.questionhint>
;您的分组数据不是,也永远不会是IList<Model.questionhint>
- 它将是IList<IGrouping<some anonymous type, Model.questionhint>>
。所以:如果您声称它是IList<Model.questionhint>
,那么您不能这样分组 - 由于分组是匿名类型,因此您无法更改返回类型以匹配。你有两个选择:
Tuple<...>
)分组,并将返回类型更改为匹配
例如:
public IList<IGrouping<Tuple<int,int,int>,Model.questionhint>>
GetRecords1(int listTask, int listActivity)
return context.questionhints
.Where(a => a.TaskID == listTask && a.ActivityID == listActivity)
.GroupBy(x => Tuple.Create(x.QuestionNo, x.ActivityID, x.TaskID))
.ToList();
【讨论】:
@user2376998 啊;不,错误在于返回错误的数据形状 - 我将在编辑中澄清【参考方案2】:改成Where(a => a.Key.TaskID == listTask && a.Key.ActivityID == listActivity)
你正在处理一个IGrouping,它的Key属性是匿名对象new x.QuestionNo, x.ActivityID, x.TaskID
这解决了最初的错误,但现在我们尝试返回 IGroupings,它不是正确的返回类型。一种更清洁的方法是
var groups = lstRecords.GroupBy(x => new x.QuestionNo, x.ActivityID, x.TaskID ).Where(a => a.Key.TaskID == listTask && a.Key.ActivityID == listActivity);
IList<Model.questionhint> questionHints = new List<Model.questionhint>();
foreach(var group in groups)
questionHints.AddRange(group);
return questionHints;
请注意,此代码未经测试。您可以在一行 linq 中完成所有这些操作(我确信 Mark 会这样做),但是为了便于阅读,我倾向于将其拆分
替代方案
如果您的目标是获取所有符合条件的 questionHint,那么简单的 Where 子句有什么问题?
lstRecords.Where(a=>a.TaskID == listTask && a.ActivityID == listActivity).ToList();
参考文献http://msdn.microsoft.com/en-us/library/bb344977.aspx
【讨论】:
感谢您的快速回复,在完成上述操作后我遇到了这个错误:无法隐式转换类型'System.Collections.Generic.List以上是关于Linq lambda 实体,不包含定义的主要内容,如果未能解决你的问题,请参考以下文章
使用 Func<T, string> lambda 动态构造 where 子句 - linq 到实体
使用实体框架 4.1 进行多表连接,我应该使用 lambda 还是 LINQ?
帮助我使用实体框架从 SQL 转换为 linq 嵌套 lambda 表达式