【问题标题】:Avoid NullReferenceException in LINQ Expression on Datatable column避免在 Datatable 列上的 LINQ 表达式中出现 NullReferenceException
【发布时间】:2016-02-02 01:05:20
【问题描述】:

我在我的数据表“文章”中遇到了空值。使用 LINQ 获取文章列表适用于 ArticleId 列,但使用“ArticleVariations”列时,空值正在杀死我。

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,我可以通过某种方式避免这种情况吗?是否可以合并两个表达式?

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您可以使用null-conditional 和空合并运算符:

    var result = this.articles.AsEnumerable()
                     .Where(r =>r.Field<String>("ArticleVariations")?.Equals(artNo) ?? false);
    

    【讨论】:

      【解决方案2】:

      这个问题很明显是因为r.Field&lt;String&gt;("ArticleVariations") retuns 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;
          });
      

      【讨论】:

        【解决方案3】:

        如果该字段可以为空,则只需反转您的测试:

        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
        }
        

        【讨论】:

          【解决方案4】:

          Where 只接受一个返回bool 的函数来确定它是否应该从集合中过滤出一个项目。您可以像任何其他函数一样使用多语句体编写它,以使空值更易于处理。这样的事情应该是一个很好的起点:

          .Where(r => {
                         string articleVariations = r.Field<string>("ArticleVariations");
                         return articleVariations != null && articleVariations.Equals(artNo);
                      });
          

          如果您想以某种方式组合这些检查以构建一个列表,其中一个或另一个给定字段与您的 artNo 匹配,您可以将其添加到函数体中。

          【讨论】:

            【解决方案5】:

            如果列包含空值,我会得到一个 NullReferenceException,我能以某种方式避免这种情况

            尽可能避免使用 instance Equals 方法。使用各自的 operatorsstatic Equals 方法,因为它们会为您正确处理 nulls。

            在您的具体情况下,最简单的方法是将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);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-08-11
              • 1970-01-01
              相关资源
              最近更新 更多