既存のデータベーステーブルの複合主キーをどのように定義する必要がありますか?

composite-primary-key ef-database-first entity-framework entity-framework-core sql-server

質問

既存のデータベースからデータを読み込む(書き込む必要はありません)コアMVCプロジェクトに取り組んでいます。残念ながら、このデータベースは完全に混乱していますが、私はそれを変更することはできません(たとえできたとしても、私は10フィートのポールでそれに触れません)。

データベースの関連する問題のいくつかは次のとおりです。

  • これらのテーブルは、お互いに外部キー関係を持たず、サブテーブルに最もよく入力されたデータを含みます。データベースを作成した人は、表をExcelスプレッドシートのように使用したようです。
  • プライマリまたは外部キーは定義されていません。
  • テーブルとカラムの名前は、含まれるデータの頭文字であるように見えます(想像上の例では、 "データベース - ビジネス顧客"の代わりに "Customer"という名前のテーブルが "dbbc"という名前になります)。
  • テーブルは「dbo」スキーマにはありません。

それにもかかわらず、私はこのデータベースからデータを読みとることを余儀なくされており、そうするためにEntity Frameworkを使用する方が好きです。

データベースはSQL Server 2008 R2でホストされています

実際の列名にマップされた適切なプロパティ名を持つクラスを使用するには、[Table]、[Column]、[Key]などの属性を使用して、使用する必要があるテーブルの1つで問題なく動作させることができます。しかし、別のテーブルが問題であることが証明されています。

このテーブルには主キーと見なすことができる単一の列を持っていませんが、私は2つの列の組み合わせは、行ごとに一意であるので、彼らは、彼らは次のように定義されていない場合でも、複合主キー(考えることができることを見出しましたそのようなデータベース内の)。

私は次のようなクラスを定義しました(私はこのデータベースのアイデンティティを隠すために名前を変更しました。

[Table("dbbo", Schema = "schema")]
public class Order
{
    [Key]
    [Column("order", Order = 0)]
    public string OrderNo { get; set; }

    [Key]
    [Column("order_line", Order = 1)]
    public string OrderLineNo { get; set; }

    [Column("qty")]
    public double Quantity { get; set; }

    [Column("pr")]
    public double Price { get; set; }
}
  • 虚構の複合主キーを構成する両方の列に[Key]属性を追加しました。
  • 私は[Column]属性のOrderプロパティに値を追加しました。これはコンポジットキーに必要であることを読んでいます。
  • 私はテーブルがこのプロジェクトに関連するより約10倍多くの列を持っているので、私は使用する必要がある列だけをマップしました。

それでも、プロジェクトを実行しようとするとエラーが発生します。

InvalidOperationException:エンティティタイプ 'MyProject.Models.Order'は、主キーを定義する必要があります。

このテーブルをEntity Frameworkと連携させるために追加できるものは何ですか?

編集:コンテキストのOnModelCreatingメソッドで定義した場合、 modelBuilder.Entity<Order>().HasKey(ord => new { ord.OrderNo, ord.OrderLineNo }); 。しかし、私はまだ可能ならば、属性だけでそれを行うことを好むでしょう。

受け入れられた回答

あなたの設定はEF6でうまくいきます。しかし、Data AnnotationsをEF Coreで使用する場合は注意が必要です(Fluent APIが推奨される方法です)。

ドキュメントのキー(プライマリ)セクションには、明示的に記載されています。

Fluent APIを使用して、複数のプロパティをエンティティのキ​​ー(コンポジットキーとも呼ばれる)に設定することもできます。コンポジットキーはFluent APIを使用してのみ設定できます。コンベンションでコンポジットキーは決して設定されず、データアノテーションを使用してコンポジットキーを設定することはできません。

だからあなたは本当に使用する必要があります:

modelBuilder.Entity<Order>().HasKey(e => new { e.OrderNo, e.OrderLineNo });


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ