【问题标题】:Linq lambda entities , does not contain definitionLinq lambda 实体,不包含定义
【发布时间】: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 语句,它说不包含ActivityIDTaskID 的定义。

完全错误:

“System.Linq.IGrouping”不包含“ActivityID”的定义,并且找不到接受“System.Linq.IGrouping”类型的第一个参数的扩展方法“ActivityID”(您是否缺少 using 指令或程序集参考?)

我的查询语句很弱,基本上我想从数据库中检索活动 id = something 和 task id = something 的记录,并按 questionNo、activityId 和 Task ID 对它们进行分组。

【问题讨论】:

  • 顺便说一句;如果 context 这里是一个提供程序,如 LINQ-to-SQL、EF 等 - 那么IList&lt;Model.questionhint&gt; lstRecords = context.questionhints.ToList(); 是一个真的 坏主意 - 这会迫使它加载整个表,在 where 等之前 - 并切换到 LINQ-to-Objects。我已经编辑了我的答案以展示如何避免这种情况

标签: c# linq lambda dao


【解决方案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&lt;T&gt;序列。

但是!您的方法声称返回IList&lt;Model.questionhint&gt;;您的分组数据不是,也永远不会是IList&lt;Model.questionhint&gt; - 它将是IList&lt;IGrouping&lt;{some anonymous type, Model.questionhint&gt;&gt;。所以:如果您声称它是IList&lt;Model.questionhint&gt;,那么您不能这样分组 - 由于分组是匿名类型,因此您无法更改返回类型以匹配。你有两个选择:

  • 不要分组
  • 按可声明的内容(自定义类型或Tuple&lt;...&gt;)分组,并将返回类型更改为匹配

例如:

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 =&gt; a.Key.TaskID == listTask &amp;&amp; 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>' 到 'System.Collections.Generic.IList'。存在显式转换(您是否缺少演员表?)
  • 问题是 Where 子句返回一个 IEnumerable> (忽略类型)。 IGrouping 是 IEnumerable,但即使我们将其简化为 IEnumerable,您也需要在返回之前将它们全部聚合在一起。这将暂时解决问题,但它远非最有效的方式(或可读方式)。
  • 这是因为我的数据库有许多属于同一个 questionNo、taskid 和 activityid 的记录,所以我需要对它们进行分组以便将它们分开。 stackoverflow.com/questions/17584451/…这是我的桌子
  • 如果您希望将它们分组,则不能返回 IList。如果你想在之后将它们分开,请在返回此函数后将它们分组。否则将失去对它们进行分组的努力(当您将它们作为列表返回时再次取消组合)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
  • 2017-08-31
  • 2019-04-15
  • 2021-03-30
  • 1970-01-01
相关资源
最近更新 更多