Если я правильно понимаю, вы хотите иметь коллекцию адресов в ваших Patient
, Vendor
и т. Д. ...
public class Patient
{
public int Id { get; set; }
public ICollection<Address> Addresses { get; set; }
}
public class Vendor
{
public int Id { get; set; }
public ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
//public int EntityKey { get; set; }
public AddressType AddressType { get; set; }
}
... и как-то сказать EF, что Patient.Addresses
только получаетзаполнены адресами типа «Пациент».
Я думаю, что это невозможно по нескольким причинам:
Если вы не выставите внешний ключ в Address
(там нет EntityKey
свойства) вы должны указать EF ключ в отображении (в противном случае он создаст / примет два разных столбца FK):
modelBuilder.Entity<Patient>()
.HasMany(p => p.PVAddresses)
.WithRequired()
.Map(a => a.MapKey("EntityKey"));
modelBuilder.Entity<Vendor>()
.HasMany(p => p.PVAddresses)
.WithRequired()
.Map(a => a.MapKey("EntityKey"));
Это выдаетисключение из-за дублирования столбца «EntityKey» для двух разных отношений.
Следующее, что мы могли бы попытаться, это показать внешний ключ как свойство в Address
(свойство EntityKey
есть), а затем используйте это отображение:
modelBuilder.Entity<Patient>()
.HasMany(p => p.PVAddresses)
.WithRequired()
.HasForeignKey(a => a.EntityKey);
modelBuilder.Entity<Vendor>()
.HasMany(p => p.PVAddresses)
.WithRequired()
.HasForeignKey(a => a.EntityKey);
Это (удивительно) не вызывает исключения, но создает два ограничения FK в базе данных между Patient
- Address
и Vendor
- Address
с тем же столбцом FK EntityKey
.Я думаю, что для вашей модели это не имеет смысла, поскольку для этого потребуется наличие Patient
и a Vendor
с одним и тем же PK, если у вас есть адрес с некоторым значением EntityKey
.Таким образом, вам придется удалить эти ограничения FK в БД вручную (что мне очень неприятно).
И последнее, что вы не можете указать фильтр для ленивых и энергичныхзагрузка навигационных свойств.Коллекция Addresses
всегда будет заполняться адресами, которые имеют тот же EntityKey
, что и PK Patient
или Vendor
соответственно.Вы можете применить фильтр с явной загрузкой:
var patient = context.Patients.Single(p => p.Id == 1);
context.Entry(patient).Collection(p => p.Addresses).Query()
.Where(a => a.Addresstype.EntityId == patientTypeEntityId)
.Load();
Но вы должны убедиться, что вы никогда не используете ленивую или энергичную загрузку для коллекции Addresses
.Таким образом, это не совсем решение, и мы должны немедленно об этом забыть.
Для меня самым уродливым является то, что вы не можете иметь ограничения FK для EntityKey
.Другими словами: БД позволяет иметь EntityKey = 1 без ссылки Patient
или Vendor
с этим PK (потому что каким-то образом пациент 1 и поставщик 1 были удалены, например).
Длятолько по этой причине я предпочел бы решение, показанное @Akash, - кроме того факта, что это, пожалуй, единственное работающее и чистое решение с EF вообще.