3

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

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

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

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

这是尝试使用.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();
4

2 回答 2

2

就像那些评论的人一样,我很惊讶您收到 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。

于 2012-08-11T04:05:04.807 回答
0

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

于 2018-04-15T07:54:04.137 回答