Lambda表达问题

时间:2011-03-30 09:52:35

标签: c# linq entity-framework-4 lambda

我是lambda表达式和linq的新手,无法弄清楚我在做错了什么:

GroupSet groupToChange = context.GroupSet.Select(q => q.groupId == groupId);

我正在尝试获取并更改实体的名称。

groupToChange.groupName = newGroupName;

我对第二行没有任何问题。有任何想法吗?它告诉我,我无法将bool转换为GroupSet,但该函数返回它找到的内容,对吧?

4 个答案:

答案 0 :(得分:5)

您想使用Where代替Select

Where返回与提供的lambda表达式匹配的所有内容 Select是一种转变。它使用提供的lambda表达式转换每个元素。

此外,Where会返回IEnumerable<T>,因为它无法知道只有一个元素符合您的条件。如果知道它只返回一个结果,则将Single附加到查询中,只返回一个元素。只有这样它才会编译:

GroupSet groupToChange = context.GroupSet.Where(q => q.groupId == groupId)
                                         .Single();

如果您不确定,一个元素是否匹配,请使用SingleOrDefault

GroupSet groupToChange = context.GroupSet.Where(q => q.groupId == groupId)
                                         .SingleOrDefault();

这两者之间的区别:
如果Single的结果集为空,Where将抛出异常 SingleOrDefault将返回default(T),即null

答案 1 :(得分:3)

GroupSet groupToChange = context.GroupSet.Where(q => q.groupId == groupId);

由于您希望按条件筛选列表,因此请使用Where而不是Select。

groupToChange将是一个集合,因此您应该将newGroupName分配给集合中的各个元素,如果它只有一个元素,则可以执行以下操作

groupToChange.Single().groupName = newGroupName;

否则你必须遍历每个元素并分配它们

foreach(var g in groupToChange)
    g.groupName = newGroupName;

另请参阅SingleOrDefault,First,FirstOrDefault方法

答案 2 :(得分:2)

Select是一个已经指出的转变,所以当你说:

.Select(q => q.groupId == groupId)

你得到的是一个布尔列表,基于GroupSet中的元素是否有一个groupId等于给定的groupId

有点像做:

List<bool> results = new List<bool>; 
foreach(group in GroupSet)
{
    results.Add(group.goupId==groupId);
}
return results;

你想要的是

  • Where将根据lambda表达式进行过滤,并返回与过滤器匹配的所有实例。
  • First将返回与lambda表达式匹配的第一个元素(如果没有则抛出异常)
  • FirstOrDefault,如果没有匹配,将返回匹配的第一个元素或默认值(在本例中可能为null)。
  • Single将返回匹配的唯一元素,如果没有一个
  • 则抛出异常
  • SingleOrDefault将返回匹配的唯一元素或默认值(可能为null)如果没有匹配,但如果有多个则抛出异常。

究竟选择哪个取决于这样的因素,列表是否总是包含匹配的元素?如果不是这样的错误条件吗?会有超过1个吗?超过1是一个错误条件。显然,如果你知道只有一个First会更快,因为当它碰到第一个时会停止,但是Single将迭代直到它检查整个列表或找到第二个元素。

答案 3 :(得分:1)

Select返回IEnumerable<TResult>并且您只想返回一个元素 - 正如Jon所说,您应该使用Single