Отношение один к нулю / одно (Code First) - PullRequest
5 голосов
/ 12 августа 2011

Я пробую этот класс:

public class Person
{
    public int PersonID { get; set; }
    public string Name { get; set; }
    public int SpouseID { get; set; }
    public virtual Person Spouse { get; set; }
}

Отношение: Один человек имеет одного или нуля Супруг / Один супруг имеет обязательное лицо

Возможно ли построить эту модельв беглом API?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 12 августа 2011

К сожалению, невозможно создать реальную самореференцию один-к-одному, потому что в настоящий момент EF не поддерживает уникальные ключи. Чтобы сделать эту реальную самореференцию один на один, SpouseID должен быть помечен как уникальный. EF допускает один-к-одному только для первичных ключей (первичный ключ в зависимом объекте должен быть также внешним ключом для основного объекта), что означает, что самоссылка отношения один-к-одному закончится PersonID <-> PersonID = двумя объектами с одинаковым PersonID в одной таблице. Это невозможно, поскольку PersonID является первичным ключом и должен быть уникальным.

Вы можете обрабатывать его как один-ко-многим и предоставлять только одно свойство навигации, как вы знаете:

modelBuilder.Entity<Person>()
            .HasOptional(p => p.Spouse)
            .WithMany()
            .HasForeingKey(s => s.SpouseID);

Для обеспечения однозначного отношения в базе данных вы добавите пользовательский инициализатор базы данных и вручную создадите уникальный индекс для столбца SpouseID.

Проблема в том, что это только односторонняя навигация, поэтому вы можете получить супруга человека, но из этого Spouse вы не можете вернуться к мужу.

2 голосов
/ 19 августа 2013

Этот ответ является предложением, а не точным.

В сценарии реального мира это неправильный дизайн, в первую очередь, у каждого из супругов есть супруг, который также ссылается на одно и то же лицо, например, Супруг (а) супруга лица - это само лицо. Мы смоделировали это в нашем приложении как Persons и PeronRelations, PersonRelations имеют свойство FromPersonID, ToPersonID и Type. Тип определяет "муж <-> жена", "жена <-> муж", "отец <-> сын", "сын <-> отец" и т. Д.

public class Person{
   public int PersonID {get;set;}
   ...
   public ICollection<PersonRelations> FromRelations {get;set;}
   public ICollection<PersonRelations> ToRelations {get;set;}

}

public class PersonRelations{

   .. 
   public int FromPersonID {get;set;}
   public int ToPersonID {get;set;}

   public RelationType Type {get;set;} 
   public Person FromPerson {get;set;}
   public Person ToPersion {get;set;}

   // useful for Employment and Marriage 
   // durations
   public DateTime? Start {get;set;}
   public DateTime? End {get;set;}
}

public enum RelationType{
   Husband_Wife,
   Wife_Husband,
   Father_Son,
   Son_Father,
   Friend_Friend,
   Employee_Employer,
   Employer_Employee
}

Это дает вам преимущество, поскольку вы можете хранить больше информации по каждому отношению и перемещаться по ним в обоих направлениях вместе со многими запросами.

Каждое отношение имеет также соответствующее противоположное отношение. И вам придется написать дополнительную логику, чтобы поддерживать правильные обратные отношения, а также для правильной работы.

И это очень легко реализовать в Entity Framework, так как это простое отношение Один-ко-многим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...