web-dev-qa-db-ja.com

2つの異なるエンティティを同じテーブルにマッピングしますか?

データベースに多くのフィールドを持つテーブルがあります。 ほとんどの場合、これらすべてのフィールドが必要です。ただし、必要なフィールドがいくつかあり、大量の行をロードするシナリオが1つあります。

エンティティを手動で追加し、それを元のテーブルにマップするだけで、不要な列は削除します。これをすべて設定しましたが、次のような自明のエラーが表示されます。

フラグメントのマッピングの問題... EntitySets 'FmvHistoryTrimmed'および 'FMVHistories'は両方ともテーブル 'FMVHistory'にマップされます。主キーが衝突する可能性があります。

これについて私がすべき他の方法はありますか?繰り返しますが、ほとんどの場合、すべての列が使用されるため、元のエンティティを削除して「余分な」フィールドを複合型にしたくありません。

39
Adam Rackis

2つの通常のエンティティを同じテーブルにマッピングすることはできません。いくつかの選択肢があります。

  1. テーブル分割を使用します。
  2. 非エンティティタイプへのプロジェクションでカスタムクエリを使用(@Aducciが提案)
  3. QueryViewを使用する
  4. データベースビューを使用するか、直接DefiningQueryを使用する

テーブル分割

テーブル分割 を使用すると、テーブルを1:1の関係で2つのエンティティにマップできます。最初のエンティティには、常に必要なPKとフィールドのサブセットのみが含まれます。 2番目のエンティティには、他のすべてのフィールドとPKが含まれます。両方のエンティティには、互いにナビゲーションプロパティが含まれます。次に、フィールドのサブセットのみが必要な場合は、最初のエンティティをクエリします。すべてのフィールドが必要な場合は、最初のエンティティをクエリして、2番目のエンティティにナビゲーションプロパティを含めます。必要に応じて、2番目のエンティティを遅延読み込みすることもできます。

QueryView

QueryView は、マッピング(MSL)で直接定義されたESQLクエリであり、新しい読み取り専用エンティティタイプにマップされます。 QueryViewを使用して、エンティティ全体のサブエンティティへの投影を定義できます。 QueryViewは、EDMXで手動で定義する必要があります(デザイナーでは使用できません)。 QueryViewは最初はコードで使用できませんが、実際には非エンティティタイプへのカスタムプロジェクションと同じです。

DefiningQuery

DefiningQuery は、ストレージモデル(SSDL)で直接定義されたカスタムクエリです。通常、DefiningQueryはデータベースビューにマッピングするときに使用されますが、カスタムSQL SELECTに使用できます。クエリの結果を読み取り専用エンティティタイプにマッピングします。 DefiningQueryは、EDMXで手動で定義する必要があります(デザイナーでは使用できません)。また、最初にコードで直接使用することもできませんが、実際にはSqlQueryDbDatabaseを呼び出すのと同じです。 DefiningQueryの問題は、SSDLで手動で定義すると、データベースからの更新モデルを使用できないことです。これは、この操作により、完全なSSDLが置き換えられ、クエリ定義が削除されるためです。

34
Ladislav Mrnka

必要なデータのみを含むデータベース上にビューを作成し、ビューをエンティティデータモデルに追加します。

データベースを変更したくない場合は、Linq toエンティティを作成するか、必要な情報のみを含むPOCOクラスに投影するESQLステートメントを作成できます。

public IQueryable<SimpleObject> GetView(DBContext context)
{
    return  (from obj in context.ComplexObjects
            select new SimpleObject() { Property1 = obj.Property1,
                                        Property1 = obj.Property2
                                      }); 
}
8
Aducci