Вы были правы, указав только одну из двух сторон отношения как внешний ключ. Сначала я подумал, что обеим сторонам нужен обнуляемый внешний ключ. Однако, если вы сделаете это, то у события 1 может быть внешний ключ для записи 2 с внешним ключом для события 3 с внешним ключом для записи 4 и т. Д.
Очевидно, что в этих ситуациях только одна из двух сторон должна иметь внешний ключ.
Глядя на Настройка отношения один-к-нулю-одному , я вижу, что достаточно:
class Event
{
public long Id { get; set; }
public string Name { get; set; }
// Every Event has zero or one Record
public virtual Record Record { get; set; }
}
class Record
{
public long Id { get; set; }
public string Name { get; set; }
// Every Record has zero or one Event
public virtual Event Event { get; set; }
}
И DbContext:
class OneToOneContext : DbContext
{
public OneToOneContext(): base("OneToOneDemo"){}
public DbSet<Event> Events { get; set; }
public DbSet<Record> Records { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Record>()
.HasOptional(record => record.Event)
.WithOptionalDependent(ev => ev.Record)
.WillCascadeOnDelete(false);
}
}
Свободный API сообщает создателю модели, что каждая запись имеет ноль или одно событие, с ноль или одну запись. Запись объявлена зависимой. Это гарантирует, что запись будет иметь иностранца в этом отношении.
Обратите внимание, что мне не нужно было добавлять другие атрибуты. Поскольку я следовал правилам первых соглашений, структура сущностей смогла обнаружить первичные ключи и связь между таблицами.
Я смог добавить: событие без записи, запись без события, событие с записью и запись с событием:
using (var dbContext = new OneToOneContext())
{
dbContext.Events.Add(new Event { Name = "Event without Record"});
dbContext.Records.Add(new Record { Name = "Record without Event" });
dbContext.Events.Add(new Event
{
Name = "Event A with Record",
Record = new Record { Name = "Record of Event A" },
});
dbContext.Records.Add(new Record
{
Name = "Record B with Event",
Event = new Event { Name = "Event of Record B" },
});
dbContext.SaveChanges();
}