【问题标题】:What's wrong with this lambda expression? "u => ... && u => ..."这个 lambda 表达式有什么问题? “你 => ... && 你 => ...”
【发布时间】:2012-03-29 12:18:03
【问题描述】:

我正在尝试在以下 lambda 表达式中使用逻辑运算符

int count = dataContext.Users.Count(u => u.ID == 1 && u.Name == "name");

下面是完整的功能

private void Login(int id, string password)
{
    MyDataContext dataContext = new MyDataContext();
    int count = dataContext.Users.Count(u => u.ID == 1 && u.Name == "name");
}

我使用的是 Microsoft SQL Server 2008 Express 2008 Edition,用户表看起来像

ID int autogenerated
Name string

但 Visual Studio 2010 给出以下设计时错误“无效的表达式术语”。知道我可能做错了什么吗?

我收到以下错误消息

  • 错误 2 ) 预期 ...\FormAdd.cs 105 123
  • 错误 3 ;预期 ...\FormAdd.cs 105 126
  • 错误 5 ;预期 ...\FormAdd.cs 105 158
  • 错误 7 ;预期 ...\FormAdd.cs 105 202
  • 错误 4 无效的表达式术语 ')' ...\FormAdd.cs 105 158
  • 错误 6 无效的表达式术语 ')' ...\FormAdd.cs 105 202
  • 错误 1 ​​无效的表达式术语 '=>' ...\FormAdd.cs 105 123

【问题讨论】:

  • Lambda 对我来说看起来不错,你确定错误在这一行吗?
  • 在 linqpad 中输入 new[] { new { ID=1, Name="name"}}.Count(u => u.ID == 1 && u.Name == "name") 对我有用。你的 ID/Name 类有错字吗?
  • "知道我可能做错了什么吗?"是的,你没有告诉我们一切。给我们完整的信息。正如所写,它看起来不错。因此,我得出结论,您遗漏了一条重要信息。
  • 您在这些图片中输入的内容与您在问题中输入的内容不同。您在问题中输入的内容是正确的。如果您想要两个条件,请使用 u => u.A == desiredA && u.B == desiredB 而不是 u => u.A == desiredA && u => u.B == desiredB

标签: c# lambda


【解决方案1】:

您在屏幕截图中显示的代码是

int count = dataContext.Users.Count(u => u.ID == 1 && u => u.Name == "name");
                                                        **

这是非法代码,下面有**的部分就是错误源。

您在问题正文中显示的代码是

int count = dataContext.Users.Count(u => u.ID == 1 && u.Name == "name");

这些是不同的。第一个是不正确的,正如 IDE 向您指出的那样。后者是正确的。

你正在使用的Count重载的签名是

 int Count<T>(this IEnumerable<T> source, Predicate<T> predicate);

这意味着在dataContext.Users上调用它,你需要提供一个Predicate&lt;User&gt;Predicate&lt;User&gt; 是将User 映射到bool 的函数。一种写法是

 static bool UserPredicate(User u) {
     return u.ID == 1 && u.Name == "name";
 }

然后你可以说

int count = dataContext.Users.Count(UserPredicate);

另一种说法是

int count = dataContext.Users.Count(
    delegate(User u) { return u.ID == 1 && u.Name == "name" }
);

这使您可以内联定义谓词。这是一个不错的功能。请注意,有效定义谓词的表达式

u.ID == 1 && u.Name == "name"

与上面定义的UserPredicate 的情况相同。

最后,Lambda 表达式可以让您摆脱一些不必要的绒毛。

int count = dataContext.Users.Count(
    u => f(u)
)

其中f(u)u 中的表达式。您可以使用的一种表达方式是

u.ID == 1 && u.Name == "name"

同样的表达方式。看,你在 IDE 中的尝试是非法的,因为你试图写

u.ID == 1 && u => u.Name == "name"

这显然不是合法的表达方式。

【讨论】:

  • 感谢 Jason 的详细解释。我是 LINQ 的新手,并没有注意到这种细微的差别。
【解决方案2】:

我尝试使用以下内容创建类似的场景:

class Program
{
    static void Main(string[] args)
    {
        var userList = new List<Users>();
        Enumerable.Range(0, 100).ToList().ForEach(x => userList.Add(new Users() { ID = x, Name = "Bob" }));

        int count = userList.Count(u => u.ID == 1 && u.Name == "Bob");

        Console.WriteLine(count);
        Console.ReadKey();
    }
}

public class Users
{
    public int ID { get; set; }
    public string Name { get; set; }
}

我没有遇到任何问题。 dataContext.Users 中是否有一些细节可能导致这种情况?您能否提供更多信息以供复制?

编辑:

在您附加的屏幕截图中,&& 后面有一个额外的 'u =>',这不起作用。

u => 用于在开始时给出表达式的主体,在 => 之后,它用于在主体中操作的参数。你在一开始就通过了 u,所以你不需要再做一次。

您能否提供类似的屏幕截图/附加信息:

int count = this.dataContext.Users.Count(u => u.ID && u.Name == "name");

相反,因为这应该表现正确?

【讨论】:

  • 更新问题,请看详情。
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
相关资源
最近更新 更多