Возьмите пример следующих сущностей Student и StudentAddress.
Настройка отношения «один к нулю или один» с использованием DataAnnotations:
public class Student
{
public Student() { }
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual StudentAddress Address { get; set; }
}
public class StudentAddress
{
[ForeignKey("Student")]
public int StudentAddressId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
}
Когда объект StudentAddress не следует соглашениям:
Если, например, сущность StudentAddress не соответствует соглашению для PK, т. Е. Другое имя для свойства Id, то вам также необходимо настроить его для PK. Рассмотрим следующую сущность StudentAddress, которая имеет имя свойства StudentId вместо StudentAddressId.
public class Student
{
public Student() { }
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual StudentAddress Address { get; set; }
}
public class StudentAddress
{
[Key, ForeignKey("Student")]
public int StudentId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
}
В приведенном выше примере нам необходимо настроить свойство StudentId как Key, а также ForeignKey. Это сделает свойство StudentId в сущности StudentAddress как PK и FK как.
Настройка отношения один-к-одному-одному с использованием Fluent API:
Когда Student и StudentAddress следуют соглашениям:
Сущности Student и StudentAddress следуют стандартному соглашению «код в начале» для PrimaryKey. Таким образом, нам не нужно настраивать их для определения их основных ключей. Нам нужно только настроить сущность StudentAddress, где StudentAddressId должен быть ForeignKey.
В следующем примере устанавливаются отношения «один к нулю» или «один» между Student и StudentAddress с использованием Fluent API.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
.HasOptional(s => s.Address) // Mark Address property optional in Student entity
.WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student
}
В приведенном выше примере сущность Student настраивается с использованием метода HasOptional (), который указывает, что свойство навигации StudentAddress в сущности Student является необязательным (не требуется при сохранении сущности Student). Затем метод WithRequired () настраивает сущность StudentAddress и при необходимости создает свойство Student Student для StudentAddress (требуется при сохранении сущности StudentAddress. Он вызывает исключение, когда сущность StudentAddress сохраняется без свойства навигации Student). Это также сделает StudentAddressId как ForeignKey.
Таким образом, вы можете настроить отношение «один к одному» или «один-один» между двумя сущностями, где сущность Student может быть сохранена без присоединения к ней объекта StudentAddress, но сущность StudentAddress не может быть сохранена без присоединения объекта сущности Student. Это требует одного конца.
Когда объект StudentAddress не следует соглашениям:
Теперь давайте рассмотрим пример объекта StudentAddress, в котором он не следует соглашению с первичным ключом, т. Е. Имя свойства Id отличается от имени Id. Рассмотрим следующие сущности Student и StudentAddress.
public class Student
{
public Student() { }
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual StudentAddress Address { get; set; }
}
public class StudentAddress
{
public int StudentId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
}
Итак, теперь нам нужно настроить свойство StudentId для StudentAddress для PrimaryKey для StudentAddress, а также ForeignKey, как показано ниже.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure StudentId as PK for StudentAddress
modelBuilder.Entity<StudentAddress>()
.HasKey(e => e.StudentId);
// Configure StudentId as FK for StudentAddress
modelBuilder.Entity<Student>()
.HasOptional(s => s.Address)
.WithRequired(ad => ad.Student);
}
Настройка отношений один-к-одному с использованием Fluent API:
Мы можем настроить отношение «один к одному» между сущностями, используя Fluent API, где требуются оба конца, то есть объект сущности Student должен включать в себя объект сущности StudentAddress, а сущность StudentAddress должна включать в себя объект сущности Student, чтобы сохранить его.
Примечание. Отношение один к одному технически невозможно в MS SQL Server. Это всегда будет один к нулю или один. EF формирует отношения один-к-одному с объектами, не находящимися в БД.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure StudentId as PK for StudentAddress
modelBuilder.Entity<StudentAddress>()
.HasKey(e => e.StudentId);
// Configure StudentId as FK for StudentAddress
modelBuilder.Entity<Student>()
.HasRequired(s => s.Address)
.WithRequiredPrincipal(ad => ad.Student);
}
В приведенном выше примере, modelBuilder.Entity (). HasRequired (s => s.Address) делает свойство Address студенческого адреса обязательным. .WithRequiredPrincipal (ad => ad.Student) делает свойство Student объекта StudentAddress соответствующим образом. Таким образом он настраивает оба требуемых конца. Так что теперь, когда вы попытаетесь сохранить сущность Student без адреса или сущность StudentAddress без Student, она выдаст исключение.
Ссылка: http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx