3

LINQ 式に基づいてデータベースから結果を返す次の関数があります。

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

リストから関数を使用しているときに関数からデータを取得しようとすると.Any、null 参照例外が発生します。

ただし、その特定の条件なしでデータを取得.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

コメントした人のように、そのステートメントを SQL にコンパイルできないという苦情ではなく、NullReferenceException を受け取ったことに驚いています。ただし、次のコードを使用すると、これを 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 に答える