C# LINQ到SQL和空字符串,如何使用Contains?

C# LINQ到SQL和空字符串,如何使用Contains?,c#,.net,linq-to-sql,C#,.net,Linq To Sql,这是一个问题 from a in this._addresses where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional) select a).ToList<Address>() 来自此中的a.\u地址 其中a.Street.Contains(Street)| a.StreetAdditional.Contains(StreetAdditional) 选择一个.ToList()

这是一个问题

from a in this._addresses
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
来自此中的a.\u地址
其中a.Street.Contains(Street)| a.StreetAdditional.Contains(StreetAdditional)
选择一个.ToList()
如果where子句中的两个属性都有值,这可以正常工作,但是如果例如a.StreetAdditional为null(大多数情况下),我将得到null引用异常

这有什么办法吗

谢谢,

最明显的一点是:

from a in this._addresses
where (a.Street != null && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>()
来自此中的a.\u地址
其中(a.Street!=null&&a.Street.Contains(Street))| |(a.StreetAdditional!=null&&a.StreetAdditional.Contains(StreetAdditional))
选择一个.ToList()

或者,您可以为Contains编写一个扩展方法,该方法接受空参数而不会出错。有人可能会说,拥有这样一个方法并不是很好,因为它看起来像一个普通的方法调用,但允许空值(从而将正常的空检查实践放在一边)。

检查以确保属性不为空

from a in this._addresses
where (a.Street != null && a.Street.Contains(street)) || 
(a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>()
来自此中的a.\u地址
其中(a.Street!=null&&a.Street.Contains(Street))|
(a.StreetAdditional!=null&&a.StreetAdditional.Contains(StreetAdditional))
选择一个.ToList()
如果null检查为false,则&&后面的第二个子句将不会计算。

来自此中的a。\u地址
from a in this._addresses
where a.Street.Contains(street) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
其中a.Street.Contains(Street)| |(a.StreetAdditional!=null&&a.StreetAdditional.Contains(StreetAdditional) 选择一个.ToList()
您必须首先检查
StreetAdditional
是否为
null

试一试


这是因为
&&
是一个快捷操作,如果
a!=null
产生false,第二个带有
null
-值的表达式将不会被计算,因为结果将是
false

我将创建一个扩展方法,如果null,则返回一个空序列,然后调用contains方法

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
      return pSeq ?? Enumerable.Empty<T>();
}

from a in this._addresses
where a.Street.Contains(street) || 
      a.StreetAdditional.EmptyIfNull().Contains(streetAdditional)
select a).ToList<Address>()
公共静态IEnumerable EmptyIfNull(此IEnumerable pSeq)
{
返回pSeq??可枚举的.Empty();
}
从本文件中的a开始。\u地址
其中a街包含(街)|
a、 StreetAdditional.EmptyIfNull()包含(StreetAdditional)
选择一个.ToList()

我会使用空合并运算符

(from a in this._addresses
where (a.Street ?? "").Contains(street) || (a.StreetAdditional ?? "").Contains(streetAdditional)
select a).ToList<Address>()
(来自此中的a.\u地址
其中(a.Street???)。包含(Street)| |(a.StreetAdditional???)。包含(StreetAdditional)
选择一个.ToList()

我认为SqlServer没有给您一个空异常。如果有,那么这段代码显然不是通过LinqToSql运行的(正如您标记的问题)


string.Contains将被转换为sql的
,与
类似,这对空值没有任何问题。

您可能需要检查以确保变量street和streetAdditional不为空。我遇到了同样的问题,将它们设置为空字符串似乎可以解决我的问题

street = street ?? "";
streetAdditional = streetAdditional ?? "";
from a in this._addresses
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
street=street??"";
streetAdditional=streetAdditional??"";
从本文件中的a开始。\u地址
其中a.Street.Contains(Street)| a.StreetAdditional.Contains(StreetAdditional)
选择一个.ToList()

需要注意的一点是,应该首先计算空值

where (**a.Street != null** && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>
其中(**a.Street!=null**&&a.Street.Contains(Street))| |(a.StreetAdditional!=null&&a.StreetAdditional.Contains(StreetAdditional))
选择一个列表

()

看起来有些奇怪,因为
null
-对象似乎能够调用成员函数??操作人员这也是我的建议。如果您觉得扩展方法使查询看起来很奇怪,您可以不使用扩展方法。您是否遇到异常?或者您是在猜测是否可能出现异常?如果您有一个
NullReferenceException
,那么您不是在执行LINQ到SQL查询。您还可以考虑不允许Street或StreetAdditional为null。如果您的数据库支持默认值,您可以将这些默认值设置为空字符串,将标志设置为不允许空值,并避免空值检查。另一方面,查询在LinqPad中确实有效。这怎么可能?为什么这两种工具在Linq到SQL行为上有如此大的差异?自定义扩展方法在Linq到SQL中不可用。这是一种更干净的方法。非常适合与iquiryable打交道
where (**a.Street != null** && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>