У меня есть много способов реализовать это, но мне любопытно, возможна ли одна конкретная реализация в EF6 с использованием Fluent API. Возьмите следующие два класса в качестве отправной точки.
class Person
{
public long Id { get; set; }
public virtual PhoneNumber PhoneNumber { get; set; }
}
class PhoneNumber
{
public long Id { get; set; }
public string AreaCode { get; set; }
public string Digits { get; set; }
}
Это оригинальная реализация, но у нее есть две проблемы.
- (в этой модели) это должно быть соотношение 1: 1. Это работает так в коде, потому что
PhoneNumber
не предоставляет ICollection<Person>
, но все же не так явно, как хотелось бы.
- Самое главное, текущий код создает детей-сирот.
.
void UpdatePhonenNumber(Person p, string areaCode, string digits)
{
// oops, lost the last one
p.PhoneNumber = new PhoneNumber { AreaCode = areaCode, Digits = digits };
}
Очевидно, я могу исправить проблему 1: 1 без особых хлопот. В этом тривиальном примере я также могу проверить на null и обновить или создать, но что, если другой код делает что-то подобное? Я тоже могу изменить этот код, но я бы предпочел что-то более автоматическое на уровне БД.
Моей первой мыслью было использование составного ключа на PhoneNumber
, но A) я должен использовать для этого свойство PhoneNumber (например, не могу добавить Person
nav nav и использовать Person.Id
) и B) Я не вижу, как я мог установить что-то вроде Person_Id
автоматически. Изменение кода для явной установки не кажется намного лучше, чем просто проверка на нулевое значение.
Я попробовал несколько вариантов этой идеи, но я пока не нашел способа заставить все это волшебным образом работать между слоями EF и DB. TLDR:
- Хотите 1: 1 между
Person
и PhoneNumber
, где Person.PhoneNumber
является необязательным, а PhoneNumber.Person
- нет (уже знаете, как это сделать).
- Хотите и назначение действовать как обновление. Если я назначу новый
PhoneNumber
, я бы хотел, чтобы EF признал, что это на самом деле просто обновление, поскольку PhoneNumber
всегда уникально для Person
.
Это выполнимо?