【问题标题】:NullReferenceException when querying Ids using LINQ and Contains [duplicate]使用 LINQ 查询 Id 时出现 NullReferenceException 并包含 [重复]
【发布时间】:2015-05-01 20:44:44
【问题描述】:

我在尝试运行以下查询时收到 NullReferenceException

 var questions = db.questions
                .Where(t => Ids.Contains(t.id));


  foreach (var q in questions) // exception
  {
   var a = q.id;
  }

foreach 语句中出现异常。

在数据库中,我有一个 questions 表,其中有一条 Id = 1 的记录。

如果我使用t => t.id == 1 查询,我会得到结果。

ID 是 List<long> 类型。运行代码时,Ids变量包含一项,即值为1。

我的目标是检索 id(主键)等于 Ids 列表中的一个或多个 Id 的问题。

例如:如果列表包含数字 1、3、5,则查询应返回问题表中与具有相应 ID 的记录匹配的行,即 1,3 和 5。

在 MySQL 中使用 Entity Framework 6。

【问题讨论】:

  • 在此处之后调用 .ToList() 会发生什么:.Where(t => Ids.Contains(t.id));,如 .Where(t => Ids.Contains(t. id)).ToList();
  • 您的 dbquestions 变量为空。你调试过你的代码吗?
  • @GrantWinney 当我使用 toList 时,我仍然得到同样的异常。我正在调试代码。
  • @IdanShechter 尝试 db.questions.ToList().Where(t => Ids.Contains(t.id)) 只是为了测试。我认为错误会消失。
  • @IdanShechter 我知道它会起作用,但它会在从 db 获取记录后应用过滤器,而不是我们应该找到一些方法在 sql 本身中过滤它。只需要很少的记录,为什么要获取所有记录?

标签: c# sql asp.net linq entity-framework


【解决方案1】:

我找到了解决方法。

  static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
    {
        if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }
        if (null == values) { throw new ArgumentNullException("values"); }
        ParameterExpression p = valueSelector.Parameters.Single();
        // p => valueSelector(p) == values[0] || valueSelector(p) == ...
        if (!values.Any())
        {
            return e => false;
        }
        var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
        var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

比使用:

  var questions = db.questions.Where(
                    BuildContainsExpression<question, long>(e => e.id, Ids));

我从here得到的解决方案

【讨论】:

    【解决方案2】:

    如果这是你的身份证

     List<long> Ids = new List<long> {1, 3, 5};
    

    这是一个示例问题列表

    var questions = new List<Questions>()
                            {
                                new Questions {Id = 1},
                                new Questions {Id = 3},
                                new Questions {Id = 5},
                                new Questions {Id = 4}
                            }
    

    这条线应该可以正常工作。

    var result = questions.Where(e => Ids.Contains(e.Id)).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 2018-11-06
      • 2014-01-01
      • 2011-01-23
      • 1970-01-01
      相关资源
      最近更新 更多