避免在数据表列上的 LINQ 表达式中使用 NullReferenceException
本文关键字:表达式 NullReferenceException LINQ 数据表 | 更新日期: 2023-09-27 18:32:43
我在我的数据表"文章"中被困在空值上。使用 LINQ 获取文章列表适用于列 ArticleId,但对于列"文章变体",空值正在杀死我。
var result = this.articles.AsEnumerable().Where(r =>r.Field<String>("ArticleId").Equals(artNo)); // works. no nulls there ;)
var result = this.articles.AsEnumerable().Where(r =>r.Field<String>("ArticleVariations").Equals(artNo)); // stuck with nulls here
如果列包含空值,我会得到一个 NullReferenceException,我可以以某种方式避免这种情况吗,是否可以合并两个表达式?
您可以使用空条件和空合并运算符:
var result = this.articles.AsEnumerable()
.Where(r =>r.Field<String>("ArticleVariations")?.Equals(artNo) ?? false);
问题显然是因为r.Field<String>("ArticleVariations")
重新调整null
。因此,在调用Equals
之前,您必须检查null
。
为此,您可以在 LINQ 表达式中调用多个语句:
var result = this.articles.AsEnumerable().Where(r => {
var res = r.Field<String>("ArticleVariations");
if (res != null) return res.Equals(artNo);
else return false;
});
如果该字段可以为空,则只需反转测试:
var result = this.articles.AsEnumerable().Where(r => artNo.Equals(r.Field<String>("ArticleVariations")));
然后,您需要做的就是在进行调用之前检查artNo
是否为空:
List<Type> result;
if (string.IsNullOrWhiteSpace(artNo))
{
result = new List<Type>();
}
else
{
result = this.articles.... as before
}
Where
只接受一个返回bool
的函数,以确定它是否应该从集合中过滤出一个项目。 你可以像任何其他函数一样使用多语句体来编写它,以使空值更容易处理。像这样的东西应该是一个很好的起点:
.Where(r => {
string articleVariations = r.Field<string>("ArticleVariations");
return articleVariations != null && articleVariations.Equals(artNo);
});
如果您想以某种方式组合这些检查以构建一个列表,其中给定字段中的一个或另一个与您的artNo
匹配,您可以将其添加到函数体中。
如果列包含空值,我得到一个空引用异常,我能以某种方式避免这种情况吗
尽可能避免使用实例Equals
方法。使用相应的运算符或静态Equals
方法,因为它们可以正确处理null
。
在您的具体情况下,最简单的方法是将Equals
替换为==
:
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleId") == artNo);
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleVariations") == artNo);
是否可以合并两个表达式?
这取决于您所说的"合并"它们是什么意思。如果您的意思是通过传递的artNo
匹配文章或变体,那么您可以使用这样的东西
var result = this.articles.AsEnumerable()
.Where(r => r.Field<string>("ArticleId") == artNo
|| r => r.Field<string>("ArticleVariations") == artNo);