Idを保持する共通の基本クラスから派生する必要があるいくつかのクラスがあります。現時点ではこれらの1つを除くすべてを無視して、次のように考えます。
public class MyBase {
[Key]
public int Id { get; set; }
}
public class MyName : MyBase {
public string Name { get; set; }
}
私のコンテキスト(DataContext)は次のようになります。
public DbSet<MyName>MyNames { get; set; }
// to avoid having EF make a MyBases table and instead map
// MyBase.Id into MyNames and my other derived classes I do this ...
protected override void OnModelCreating((DbModelBuilder modelBuilder) {
modelBuilder.Entity<MyBase>()
.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<MyName>()
.Map(m => {
m.MapInheritedProperties();
m.ToTable("MyNames");
});
}
結果のDBで、Enable-Migrations、Add-Migration Initial、およびUpdate-Databaseを実行すると、MyBasesというテーブルが取得されず、代わりにMyNamesのId列が取得されます。
dbo.MyNames
-----------
Id (PK, int, not null)
Name (nvarchar(max), null)
これまでのところ、すべてがコンパイルおよびビルドされ、次のようなものを使用してテストします。
using ( DataContext dc = new DataContext()) {
var jj = new MyName { Name = "Janice Joplin" };
dc.MyNames.Add(jj);
dc.SaveChanges();
var jh = new MyName { Name = "Jimmy Hendrix" };
dc.MyNames.Add(jh);
dc.SaveChanges();
}
これは最初は機能します(JaniceはId = 0で追加されます)がnot 2回目... Jimmyは重複キー例外を受け取ります。注(完全な開示のため)私は実際にコードの別の部分でjjおよびjhオブジェクトを作成し、それらをMyBaseオブジェクトとしてこのメソッド(上記)に渡し、それがMyNameオブジェクトである場合はそれらをMyNameオブジェクトにキャストバックしています。それが問題にならないことを願っています。
すべてが1つのテーブルにある場合、IDはIDとしてマークされ、@@ IDENTITYを使用してオブジェクトID値を割り当てることができると思います。おそらく、結局、MyBasesテーブルを作成し、最初にそのレコードを作成してから、トランザクションでIdを派生テーブルに複製する必要があります。これに対する最善のアプローチは何ですか?
このEF6 CodeFirst初心者のための任意の助けをいただければ幸いです。ありがとう。
EFを使用していたときに、Identityを使用してテーブルを作成し、クラスでid列を
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
だから私はあなたのコードが
modelBuilder.Entity<MyBase>()
.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
問題は、EF6 Code First Migrationsを使用しているという事実にあると思います。その場合は、.AddOrUpdate()メソッドを使用してDBをシードする必要があります。 このスタックオーバーフローの質問 がそれをカバーしています。