带有.Any条件的Linq查询返回nullreference异常

时间:2012-07-31 13:08:12

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

我有以下函数,它根据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<T>实现上做这样的操作?

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

2 个答案:

答案 0 :(得分:2)

与那些评论过的人一样,我很惊讶你得到了一个N​​ullReferenceException,而不是抱怨无法将该语句编译成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。

答案 1 :(得分:0)

当source为null时,Queryable.Any()返回一个ArgumentNullException,如下所示:https://msdn.microsoft.com/it-it/library/bb343630(v=vs.110).aspx