ユースケースの例とDB内のオブジェクトの個別の作成EFコードファースト:TFT継承
ユーザーが(Usersテーブルにレコードを追加する)、ウェブサイト上で登録しています。その後、電子メールに行き、登録を確認します。確認リンクは人編集フォームのページにリダイレクトされ、ユーザーはフォームを入力して送信します(Personsテーブルにレコードを追加します)。
技術説明
IはEFモデルで定義された単純な2オブジェクト表ペル型継承を有します。
エンティティ
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
public class Person : User
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
データベース
public class MainDataContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var configs = modelBuilder.Configurations;
configs.Add(new UserConfiguration());
configs.Add(new PersonConfiguration());
}
}
構成
internal class UserConfiguration : EntityTypeConfiguration<User>
{
internal UserConfiguration()
{
ToTable("Users");
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Name)
.IsRequired()
.HasMaxLength(128);
Property(x => x.Password)
.IsRequired()
.HasMaxLength(128);
Property(x => x.Email)
.IsRequired()
.HasMaxLength(128);
}
}
internal class PersonConfiguration : EntityTypeConfiguration<Person>
{
internal PersonConfiguration()
{
ToTable("Persons");
Property(x => x.FirstName)
.IsRequired()
.HasMaxLength(16);
Property(x => x.MiddleName)
.IsOptional()
.HasMaxLength(16);
Property(x => x.LastName)
.IsRequired()
.HasMaxLength(16);
}
}
一貫DbSetsにリンク(FK)オブジェクトを作成する必要が
、このような何か:
var db = new MainDataContext();
var user = new User
{
Name = "someUser",
Password = "somePassword",
Email = "someEmail"
};
db.Users.Add(user);
db.SaveChanges();
// After some time in other some place
var person = new Person
{
Id = user.Id,
FirstName = "someFirstName",
LastName = "someLastName"
};
db.Persons.Add(person);
db.SaveChanges();
最後のSaveChanges DbEntityValidationErrorをキャッチした後:「検証は、1つのまたは複数のエンティティに失敗しました。詳細については、「EntityValidationErrors」プロパティを参照してください。」必要なユーザーのフィールドの3個の検証エラーがあります。
別途FK(継承)でacociatedさDbSetsにエントリを追加する方法は?
UPDATE
私は1つの解決策を見つけましたが、古いユーザーを削除する必要があります。ユーザーテーブルが他のテーブルに関連付けられている場合、削除することができなくなるため、取り除かずにこれを行う必要があります。
var db = new MainDataContext();
var user = new User
{
Name = "someUser",
Password = "somePassword",
Email = "someEmail"
};
db.Users.Add(user);
db.SaveChanges();
// After some time in other some place
var person = new Person
{
Id = user.Id,
Name = user.Name,
Password = user.Password,
Email = user.Email,
FirstName = "someFirstName",
LastName = "someLastName"
};
db.Users.Remove(user);
db.Persons.Add(person);
db.SaveChanges();
しかし、もう1つの問題がありました - personオブジェクトの新しいGuidが生成されました。
どのようにユーザーの古いレコードを削除せずに問題を解決するには?
ユーザーはユーザーを継承するため、名前、パスワード、および電子メールを指定する必要があります。データベースはどのように見えますか? Personテーブルには、UserテーブルのフィールドまたはFKだけのUserテーブルのすべてのフィールドがありますか?後であれば、エンティティは間違っています。 – cadrell0
@ cadrell0私が前に述べたように、テーブルをオブジェクト階層にマップする方法では、テーブルごとの型(ユーザーテーブルにはFKのみ)を使用します。以下はdb図の[image](http://dl.dropbox.com/u/5522431/TPT.png)です。 – ebashmakov
なぜPersonはUserから継承しているのですか? – cadrell0