LINQ 結合とメモリ内コレクションのトラブルシューティング
メモリ内コレクション (この例では ppCombined
など) を直接組み込もうとすると、「型の定数値を作成できません...このコンテキストではプリミティブ型または列挙型のみがサポートされています」というエラーがよく表示されます。データベースの LINQ クエリに変換します。 これは、データベース クエリがデータベース常駐データのみを操作するためです。 メモリ内データとの結合は直接サポートされていません。
この問題は通常、Select
ステートメントの Join
節内で発生します。 メモリ内コレクションから設定されたプロパティを含む PersonDTO
オブジェクトを作成しようとすると、競合が発生します。
LINQ JOIN 失敗の根本原因
このエラーは、データベース クエリの Where
ステートメントの ppCombined
内 で コレクションに対してフィルタリング操作 (Select
句) を実行しようとしたときに発生します。 データベース エンジンは、このメモリ内操作を独自の同等の操作に変換できません。
解決策: データベース操作とメモリ内操作を分離する
解決策は、データベース クエリをメモリ内処理から分離することです。 これには、最初にデータベース クエリを実行し、次に結果のメモリ内データセットに対してフィルタリングとデータ操作を実行することが含まれます。 AsEnumerable()
メソッドがここで重要です。 データベース クエリを強制的に実行し、結果を IEnumerable
オブジェクトとして返し、後続の操作を完全にメモリ内で実行できるようにします。
修正されたコードは次のとおりです:
<code class="language-csharp">var persons = db.Favorites .Where(f => f.userId == userId) .Join(db.Person, f => f.personId, p => p.personId, (f, p) => new { personId = p.personId, addressId = p.addressId, favoriteId = f.favoriteId }) .AsEnumerable() // Database query completes here .Select(x => new PersonDTO { personId = x.personId, addressId = x.addressId, favoriteId = x.favoriteId, personProtocol = ppCombined .Where(p => p.personId == x.personId) .Select(p => new PersonProtocol { personProtocolId = p.personProtocolId, activateDt = p.activateDt, personId = p.personId }) .ToList() });</code>
AsEnumerable()
を使用すると、データベース クエリが完了し、後続の Select
ステートメントはデータベースから取得したデータのみに対して動作し、メモリ内の ppCombined
コレクションとの非互換性が解決されます。 これにより、クエリが正常に実行されます。
以上がインメモリ コレクションを使用すると LINQ JOIN が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。