2012-04-25 65 views
4

我有一个非常简单的帮助方法来生成唯一的代码。为了确保代码是唯一的,我执行一个LINQ to Entities查询来验证它尚未被使用。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中是否全部坏了或发生了什么?

+0

如果Jon的权利,这是R#错误重构,那么我建议你也向他们汇报。虽然我意识到可能很难发现当这样的条件被评估为SQL时! – Rup 2012-04-25 11:41:42

+0

我想这是一个常见的情况,他们可能会考虑它 - 会增加一个问题,并看看会发生什么。 – 2012-04-25 12:51:39

+0

问题补充:http://youtrack.jetbrains.com/issue/RSRP-297527 – 2012-04-25 13:03:21

回答

4

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

只是一个猜测,但它是我以前见过的那种东西。你可以尝试:

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

你说得很对 - 添加空检查使其工作。不是特别直观,但这是必需的。 – 2012-04-25 12:49:57

+0

@MortenMertner:不,我同意:) – 2012-04-25 12:51:24

0

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

我猜表情很好。后面的数据应该有问题

+0

“如果SignUpCode为空,应该抛出空引用异常”如果表达式在C#中计算,是的 - 但它可能被转换为SQL来进行评估,处理语义。 – Rup 2012-04-25 11:38:33