先日OneToManyやったので今日はOneToOneをやってみたいと思います。
こんな感じのクラスを定義します。
public class Person { public int Id { get; set; } public string Name { get; set; } public PersonDetail Detail { get; set; } } public class PersonDetail { public int Id { get; set; } public int Age { get; set; } public int PersonId { get; set; } public Person Person { get; set; } }
そしてDbContextを以下のような雰囲気で定義します。HasOne, WithOne, ForeignKeyのパターンです。何故かForeignKeyにはラムダ式を指定するオーバーライドもあるのですがエラーになったので型と列名を指定するオーバーライドを使ってます。
public class SampleContext : DbContext { public DbSet<Person> People { get; set; } public DbSet<PersonDetail> PersonDetails { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("filename=sample.db"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { var people = modelBuilder.Entity<Person>(); people.ToTable("People"); var personDetails = modelBuilder.Entity<PersonDetail>(); personDetails.ToTable("PersonDetails"); personDetails.HasOne(x => x.Person) .WithOne(x => x.Detail) .HasForeignKey(typeof(PersonDetail), nameof(PersonDetail.PersonId)) .OnDelete(Microsoft.Data.Entity.Metadata.DeleteBehavior.Restrict); } }
こんな感じで実行できます。
// データ突っ込む using (var ctx = new SampleContext()) { ctx.People.Add(new Person { Name = "Tanaka", Detail = new PersonDetail { Age = 30 } }); ctx.SaveChanges(); } // データとってくる using (var ctx = new SampleContext()) { var p = ctx.People.Include(x => x.Detail).First(); Debug.WriteLine($"{p.Name} {p.Detail.Age}"); }