为什么连接到非空字符串的空字符串计算为null?

时间:2012-06-08 00:13:35

标签: c# .net linq linq-to-entities

 var users=db.Users.Where(u => u.Name.StartsWith(term) || u.Email.StartsWith(term) || u.FirstName.StartsWith(term)).ToArray();
 var jsos=users.Select(u => new { label = u.FirstName  +" "+  u.Name+ " (" + u.Email+")", value = u.Id });

按预期工作。但是,如果没有ToArray(),我会得到看似奇怪的行为:null firstName会导致标签被评估为null。使用ToArray(),我得到了预期的行为。 (null被视为空字符串并连接到其他非空字符串)。为什么呢?

2 个答案:

答案 0 :(得分:7)

在SQL世界中,根据定义,任何具有NULL作为其一部分的表达式都将变为NULL。这是因为NULL意味着一个不确定的值 - 一个不确定的值+其他任何值仍然是一个不确定的值,即NULL。

同样,在SQL中,您可以使用COALESCE之类的东西将NULL转换为空字符串 - 我不记得linq等价物是什么。

答案 1 :(得分:1)

使用.ToArray(),您将Linq用于.NET类型,该类型在代码中进行评估并使用.NET类型处理。这里,字符串连接方法按照您习惯的方式工作。

如果没有.ToArray,您的查询将在DBMS中执行,并使用系统配置用于NULL值的任何内容。

在这种情况下,DBMS配置为根据ANSI标准处理NULL,这与.NET在某些地方非常不同。您应该查找ANSI NULL以查找详细信息。这并不复杂,但如果你不期待它可能会令人困惑。

两个附录 1)首先,我认为NULL的串联规则是在ANSI标准中规定的,但实际上我意识到我可能是错的。我来自SQL Server背景,其中ANSI_NULLS是控制NULL相等的设置,而连接由另一个控制。如果我错误地将后者与前者联系起来,我道歉。

2)尽管我讨论了可配置性,以及SQL Server至少允许更改配置这一事实,但绝对是您所看到的行为是标准,默认和预期的情况。如果你要使用数据库,你应该习惯它。