【问题标题】:LINQ to Entities: All method not yielding the expected resultLINQ to Entities:所有方法均未产生预期结果
【发布时间】:2012-04-25 19:38:45
【问题描述】:

我有一个非常简单的辅助方法来生成唯一代码。为了确保代码是唯一的,我执行了一个 LINQ to Entities 查询来验证它是否已经在使用中。

我第一次尝试编写此方法时效果很好:

public string GenerateUniqueSignUpCode()
{
    while( true )
    {
        var code = Path.GetRandomFileName().Substring( 0, 6 ).ToUpper();
        if( !Context.Users.Any(e => e.SignUpCode.ToUpper() == code) )
            return code;
    }
}

但是,R# 建议可以简化 LINQ 表达式,从而产生了这种方法:

public string GenerateUniqueSignUpCode()
{
    while( true )
    {
        var code = Path.GetRandomFileName().Substring( 0, 6 ).ToUpper();
        if( Context.Users.All(e => e.SignUpCode.ToUpper() != code) )
            return code;
    }
}

这种重写会导致无限循环。当代码运行时,数据库不包含任何 6 字符代码,因此它应该在第一次尝试时退出循环(如第一个方法所示)。

在 EF 4.3.1 中是否全部损坏或发生了什么?

【问题讨论】:

  • 如果 Jon 是对的,而且这被证明是 R# 的错误重构,那么我建议你也向他们报告。虽然我意识到当这样的条件被评估为 SQL 时可能很难发现!
  • 我想这是一个足够常见的案例,他们可能会考虑它 - 会为它添加一个问题,看看会发生什么。

标签: c# entity-framework entity-framework-4 linq-to-entities


【解决方案1】:

我的猜测是,如果 SignupCode 对于任何条目为空,就会发生这种情况。使用!= 进行比较不会给出“真”结果,因此All 将返回假。

只是一个猜测,但这是我以前见过的那种事情。你可以试试:

if (Context.Users.All(e => e.SignUpCode == null ||
                           e.SignUpCode.ToUpper() != code))

【讨论】:

  • 你说的很对——添加空检查使它起作用。虽然不是特别直观,但这是必需的。
  • @MortenMertner:不,我同意 :)
【解决方案2】:

Context.Users.All(e => e.SignUpCode.ToUpper() != code 如果 SignUpCode 为 null,则应抛出 null 引用异常。

我想表达一切都很好。后面的数据应该有问题

【讨论】:

  • “如果 SignUpCode 为 null,则应抛出 null 引用异常”如果表达式在 C# 中进行评估,是的 - 但它可能正在转换为 SQL 进行评估,这会改变 null 处理语义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多