【问题标题】:Linq Query with .Any condition returns nullreference exception具有 .Any 条件的 Linq 查询返回空引用异常
【发布时间】:2012-07-29 06:18:17
【问题描述】:

我有以下函数,它根据 LINQ 表达式从数据库返回结果:

IQueryable<TEntity> FindAll<TEntity>(Expression<Func<TEntity, bool>> expression)

当我在使用列表中的.Any 函数时尝试从函数中提取数据时,我得到一个空引用异常。

但是,当我在没有特定条件的情况下提取数据并在每个循环中使用相同的 .Any 函数时,一切正常。

这是尝试使用不起作用的 .Any 函数的调用:

var ppcReports = repository.FindAll<PPCReport>(
    x => x.ClientId == clientId && 
    (campaigns.Any(c=> c.Id == x.CampaignId))
).ToList();

以及它正常工作的方式:

var ppcReports = repository.FindAll<PPCReport>(
    x => x.ClientId == clientId).ToList();

foreach (var item in ppcReports)
{
    if (campaigns.Any(c => c.Id == item.CampaignId))
    {
        // do something
    }
}

我想知道为什么会发生这种情况,我做错了什么是在查询完成之前无法过滤结果吗?

通过在过滤结果之前调用.ToList() 确实有效,所以我想我不能对IQueryable&lt;T&gt; 实现执行这样的操作?

var ppcReports = repository.
    FindAll<PPCReport>(x => x.ClientId == clientId).
    ToList().
    Where(w => campaigns.Any(c => c.Id == w.CampaignId)).
    ToList();

【问题讨论】:

  • 空异常? Sql 不会抛出那个。 campaigns 是本地序列吗?第一个 sn-p 总是使用这个。仅当 FindAll 返回非空可枚举时,第二个才使用它。编辑:在您的编辑之后,我几乎可以确定 campaigns 为空。在第一个代码中,linq 试图用它进行查询(无论如何它都会失败,因为它是本地序列)。在第二个代码中你可能没有进入循环。
  • 您是否跟踪到数据库的 sql 请求(来自 ef)?顺便说一下,不要使用 ToList() 来迭代 IQueriable,使用 ToArray()
  • campaigns 是一个本地 List 已从数据库中填充的列表,我无法理解的是为什么它在填充列表并与仅检查的 Any 方法一起使用时返回空异常如果该列表中有任何元素,则无论如何它都不应该返回空异常。在这种情况下我使用的是 NHibernate,我没有尝试将 sql 跟踪到数据库,我将在今天晚些时候尝试。

标签: asp.net linq asp.net-mvc-2 iqueryable


【解决方案1】:

与评论的那些人一样,我很惊讶您收到 NullReferenceException 而不是抱怨无法将该语句编译为 SQL。但是,以下代码应该让您在 1 个查询中执行此操作(并将在 SQL 中执行所有过滤):

var campaignIds = (campaigns ?? Enumerable.Empty<Campaign>())
    .Select(c => c.Id);
var ppcReports = repository
    .FindAll<PPCReport>(pr => pr.ClientId == clientId
        && campaignIds.Contains(pr.CampaignId))
    .ToList();

这应该适用于 EF 和 Linq-to-SQL。

【讨论】:

    【解决方案2】:

    当源为空时,Queryable.Any() 返回 ArgumentNullException,如下所述:https://msdn.microsoft.com/it-it/library/bb343630(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-25
      • 2023-03-31
      • 2018-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-09
      • 2012-09-29
      相关资源
      最近更新 更多