避免在数据表列上的 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,我可以以某种方式避免这种情况吗,是否可以合并两个表达式?

避免在数据表列上的 LINQ 表达式中使用 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);