先日OneToManyやったので今日はOneToOneをやってみたいと思います。
こんな感じのクラスを定義します。
publicclass Person { publicint Id { get; set; } publicstring Name { get; set; } public PersonDetail Detail { get; set; } } publicclass PersonDetail { publicint Id { get; set; } publicint Age { get; set; } publicint PersonId { get; set; } public Person Person { get; set; } }
そしてDbContextを以下のような雰囲気で定義します。HasOne, WithOne, ForeignKeyのパターンです。何故かForeignKeyにはラムダ式を指定するオーバーライドもあるのですがエラーになったので型と列名を指定するオーバーライドを使ってます。
publicclass SampleContext : DbContext { public DbSet<Person> People { get; set; } public DbSet<PersonDetail> PersonDetails { get; set; } protectedoverridevoid OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("filename=sample.db"); } protectedoverridevoid 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}"); }