Обновление: я должен был заметить, что свойство Id
на NavigationPropertyClass
не создано сгенерированной базой данных. В моей реальной модели NavigationPropertyClass
также является частью схемы иерархии (с использованием TPH), которая здесь не показана, и, хотя у NavigationPropertyClass
есть экземпляр DerivedClass1
и коллекция экземпляров DerivedClass2
, это не обязательно относится ко всем классам, которые наследуют от базовый класс, из которого выведено значение NavigationPropertyClass
.
Часть моей модели выглядит примерно так (другие свойства и конструкторы опущены для краткости):
//Many other classes inherit from this class
//and many of the derived classes are not composed of DerivedClass1 or DerivedClass2
public abstract SomeOtherBaseClass{
public int Id {get; set;} //not database generated, set in the constructor
}
public NavigationPropertyClass: SomeOtherBaseClass{
public DerivedClass1 Derived1 {get; set;}
public virtual ICollection<DerivedClass2> Derived2Collection {get; set;}
}
public abstract class BaseClass{
public int Id {get; set;}
//other properties shared by derived classes
}
public class DerivedClass1: BaseClass{
public NavigationPropertyClass NavigationProperty {get; set;}
//other properties pertinent to DerivedClass1
}
public class DerivedClass2: BaseClass{
public NavigationPropertyClass NavigationProperty {get; set;}
//other properties pertinent to DerivedClass2
}
DerivedClass1
имеет отношение 1-1 с NavigationPropertyClass
, в то время как DerivedClass2
имеет много-1 отношения с NavigationPropertyClass
.
Я пытаюсь настроить идентификационные отношения в каждом из производных классов, так что, когда экземпляр NavigationPropertyClass
будет удален из базы данных, также будет связан соответствующий экземпляр DerivedClass1
и любых экземпляров DerivedClass2
. Единственный способ, которым я могу это понять, - это наследование TPT, но даже в этом случае я не могу нормально работать. Я бы опубликовал свою конфигурацию Fluent API, но на данный момент я пробовал так много перестановок, что не знаю, какой из них следует публиковать.
Есть ли способ сделать то, что я пытаюсь сделать? Если да, то как выглядит API Fluent API?
Это модели, которые соответствуют вашим требованиям.
public abstract class Base
{
public int Id { get; set; }
}
public class Derived1 : Base
{
public int PropDerived1 { get; set; }
public NavigationPropertyClass NavigationProperty { get; set; }
}
public class Derived2 : Base
{
public int PropDerived2 { get; set; }
public int NavigationPropertyClassId { get; set; }
public NavigationPropertyClass NavigationPropertyClass { get; set; }
}
public abstract class SomeOtherBaseClass
{
public int Id { get; set; }
}
public class NavigationPropertyClass : SomeOtherBaseClass
{
public Derived1 Derived1 { get; set; }
public virtual ICollection<Derived2> Derived2s { get; set; }
}
И только вам нужно использовать ToTable
для наследования TPT при настройке построителя модели.
public class AppContext : DbContext
{
public DbSet<SomeOtherBaseClass> SomeOtherBaseClasses { get; set; }
public DbSet<Base> Bases { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Derived1>().ToTable("Derived1");
modelBuilder.Entity<Derived2>().ToTable("Derived2");
modelBuilder.Entity<NavigationPropertyClass>().ToTable("NavigationPropertyClass");
modelBuilder.Entity<NavigationPropertyClass>()
.HasRequired(x => x.Derived1)
.WithRequiredDependent(x => x.NavigationProperty);
}
}
И оставьте все для конвенции EF, за исключением той части, где NavigationPropertyClass::Id
также является FK для Derived1
.
результат
Упрощенное сгенерированное ограничение в таблице NavigationPropertyClass
:
PRIMARY KEY [Id]
FOREIGN KEY([Id]) REFERENCES [dbo].[Derived1] ([Id])
FOREIGN KEY([Id]) REFERENCES [dbo].[SomeOtherBaseClasses] ([Id])
Больше