Я не уверен, хотите ли вы следующее:
modelBuilder.Entity<Customers>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CustomerPhoneId"));
modelBuilder.Entity<Companies>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CompanyPhoneId"));
Использование MapKey
необязательно.Это просто дает столбцу внешнего ключа имя, которое вы хотите.Если вы опустите этот EF, то создадите стандартное имя (что-то с подчеркиванием: ..._Id
).
На самом деле все сопоставление является необязательным, поскольку соглашения о сопоставлении просто создают одни и те же отношения без какого-либо сопоставления Fluent API..
Таблица Phones
будет иметь два внешних ключа, допускающих нулевое значение CustomerPhoneId
и CompanyPhoneId
, относящиеся к таблице Customers
и таблице Companies
соответственно.
Редактировать
Альтернативой, которая потребует только один внешний ключ в таблице Phone
для нескольких различных объектов, будет отображение наследования:
public abstract class OrganizationsWithPhone
{
public OrganizationsWithPhone()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public ICollection<Phones> Phones { get; set; }
}
public class Customers : OrganizationsWithPhone
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Companies : OrganizationsWithPhone
{
public string Name { get; set; }
}
public class Phones
{
public Guid Id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
}
Отображение:
modelBuilder.Entity<OrganizationsWithPhone>()
.HasMany(o => o.Phones)
.WithOptional() // or .WithRequired()
.Map(m => m.MapKey("OrganizationsWithPhoneId"));
modelBuilder.Entity<OrganizationsWithPhone>()
.ToTable("OrganizationsWithPhone");
modelBuilder.Entity<Customers>()
.ToTable("Customers");
modelBuilder.Entity<Companies>()
.ToTable("Companies");
Теперь у вас есть только одно отношение внешнего ключа между Phones
и базовой таблицей OrganizationsWithPhone
, но благодаря отображению наследования существуют дополнительные взаимно-однозначные отношения между базовой таблицей и таблицами для производных объектов Customers
и Companies
.В основном количество необходимых отношений остается неизменным (или даже больше в этой модели).
В этой модели клиент и компания не могут использовать одни и те же телефонные номера, поскольку строка в таблице Phones
относится к строкеOrganizationsWithPhone
, который может быть либо клиентом, либо компанией, но не обоими одновременно.
Базовая таблица OrganizationsWithPhone
имеет только один столбец Id
.Если у вас есть более общие свойства во всех производных объектах, вы можете переместить их в базовые права.