12

最近、EF 4.2 から EF 5.0 にアップグレードされたコードがいくつかあります (.Net 4.0 で実行しているため、実際には EF 4.4 です)。クエリの構文を変更する必要があることがわかりました。その理由が知りたいです。問題から始めましょう。

クライアントによって定期的に入力される EventLog テーブルがあります。イベント ログごとに、レポート テーブルにエントリが作成されます。これは、レポート テーブルにまだエントリがないイベント ログを検出するために定期的に実行されるクエリです。EF 4.2 で使用したクエリは次のとおりです。

from el in _repository.EventLogs
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID)

EF 5.0 にアップグレードしてから、実行時に次のエラーが発生します。

System.NotSupportedException: タイプ 'Namespace.Report' の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。

結合構文で書き直したところ、問題が解決したことがわかりました。以下は EF 5.0 で機能し、ほぼ同等です。

from eventLog in _repository.EventLogs
join report in _repository.Reports on eventLog.EventlogID equals report.EventLogID into alreadyReported
where !alreadyReported.Any()

最初のクエリの構文/スタイルが混在していることについて意見が分かれている人もいるかもしれませんが、私はその理由にもっと興味があります。EF 4.2 コンパイラが元のクエリの SQL を生成できたのに、EF 5.0 が拒否するのは奇妙に思えます。これは私が見逃している設定ですか、それとも 2 つの間の制約を強化しているだけですか? なぜこうなった?

4

2 に答える 2

2

この問題は、リポジトリから返される型が原因です。問題が再現できて_repository.Reportsいない場合IQueryable<T>。その場合、Reportsは非スカラー変数と見なされます。ちなみにLINQでは許可されていません。サポートされていない非スカラー変数の参照を参照してください

2番目のクエリが機能する理由に関する質問については、基本的には、IQueryable<T>グループが結合する次の拡張メソッドですIEnumerable<TInner>

public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
    this IQueryable<TOuter> outer,IEnumerable<TInner> inner,
    Expression<Func<TOuter, TKey>> outerKeySelector,
    Expression<Func<TInner, TKey>> innerKeySelector,
    Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector)

(非スカラー変数を参照する代わりに) 外部と内部の両方のキー セレクターの式を受け入れるだけです。上記の制約が適用されない場合。

注:最初のクエリの場合_repository.Reportsは機能します。IQueryable<T>EF は式ツリーを正しく構築し、適切な SQL を実行するためです。

于 2013-10-02T08:42:44.173 に答える
0

念のため、変換してみましたか

from el in _repository.EventLogs
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID)

from el in _repository.EventLogs
where !_repository.Reports.Where(p => p.EventLogID == el.EventlogID).Any();

また

from el in _repository.EventLogs
where !_repository.Reports.Where(p => p.EventLogID == el.EventlogID).Count() > 0;
于 2013-09-25T13:56:04.967 に答える