我有一个关于 EF 5.0 和继承对象映射到与超类相同的表的问题。
我的项目如下所示:
public class ContextA : DbContext
{
public DbSet<EntityA> EntitiesA { get; set; }
public DbSet<EntityB> EntitiesB { get; set; }
public ContextA(string connnectionString) : base(connnectionString) { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
ModelCreating(modelBuilder);
}
public static void ModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityA>().ToTable("EntityAs");
modelBuilder.Entity<EntityB>().ToTable("EntityBs");
modelBuilder.Entity<EntityA>().HasKey(e => e.EntityAId);
modelBuilder.Entity<EntityB>().HasKey(e => e.EntityBId);
}
}
public class EntityA
{
public int EntityAId { get; set; }
public string Name { get; set; }
}
public class EntityB
{
public int EntityBId { get; set; }
public string Name { get; set; }
public int EntityAId { get; set; }
}
很好很好。请记住,实体 A 和 B 可能位于数据库的不同模式中,或者可能位于不同的上下文中,这就是 statc ModelCreation 方法的原因。
现在我想组合这样的上下文:
public class ContextB : DbContext
{
public DbSet<EntityAA> EntityAAs { get; set; }
public DbSet<EntityBB> EntityBBs { get; set; }
public ContextB(string connnectionString) : base(connnectionString) { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
ModelCreating(modelBuilder);
}
public static void ModelCreating(DbModelBuilder modelBuilder)
{
ContextA.ModelCreating(modelBuilder);
modelBuilder.Entity<EntityAA>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("EntityAs");
}).HasKey(e => e.EntityAId)
.Property(e => e.EntityAId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<EntityBB>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("EntityBs");
})
.HasKey(e => e.EntityBId)
.Property(e => e.EntityBId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<EntityAA>()
.HasMany(ea => ea.EntityBs)
.WithRequired(eb => eb.EntityA)
.HasForeignKey(eb => eb.EntityAId);
}
}
public class EntityAA : EntityA
{
private readonly List<EntityBB> _entityBbs = new List<EntityBB>();
public virtual ICollection<EntityBB> EntityBs
{
get { return _entityBbs; }
}
}
public class EntityBB : EntityB
{
public EntityAA EntityA { get; set; }
}
我想这样做,因为我想拥有特定于模式的上下文,我想将它们组合到特定于应用程序的上下文中。
现在的问题是,我在模型创建过程中遇到错误:
Ergebnis Meldung: Die EfInheritance.Test.GlobalTests.InsertEntitiesContextB-Testmethode hat eine Ausnahme ausgelöst: System.InvalidOperationException: The foreign key component 'EntityAId' is not a declared property on type 'EntityBB'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.
Ergebnis StackTrace:
bei System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.ForeignKeyConstraintConfiguration.Configure(EdmAssociationType associationType, EdmAssociationEnd dependentEnd, EntityTypeConfiguration entityTypeConfiguration)
bei System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.ConfigureConstraint(EdmAssociationType associationType, EdmAssociationEnd dependentEnd, EntityTypeConfiguration entityTypeConfiguration)
bei System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.ConfigureDependentBehavior(EdmAssociationType associationType, EdmModel model, EntityTypeConfiguration entityTypeConfiguration)
bei System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.Configure(EdmNavigationProperty navigationProperty, EdmModel model, EntityTypeConfiguration entityTypeConfiguration)
bei System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigureAssociations(EdmEntityType entityType, EdmModel model)
bei System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType entityType, EdmModel model)
bei System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel model)
bei System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
bei System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
bei System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
bei System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
bei System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
bei System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
bei System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
bei System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
bei System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
bei System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
bei System.Data.Entity.DbSet`1.Add(TEntity entity)
bei EfInheritance.Test.GlobalTests.InsertEntitiesContextB() in c:\temp\EfInheritance\EfInheritance.Test\GlobalTests.cs:Zeile 45.
最后,我的问题是:
- 有可能像这样工作吗?
- 如果这是一个可能的解决方案,我该怎么做才能让它工作?
如果我在 ModelCreation 中注释 ForeignKey-Statement,它可以正常工作,除了运行简单测试后数据库中的结果:
using (var ctx = new ContextB("CodeFirstDatabase"))
{
EntityAA aa = new EntityAA();
aa.Name = "Test_AA_01";
EntityBB bb = new EntityBB();
bb.Name = "Test_BB_01";
aa.EntityBs.Add(bb);
ctx.EntityAAs.Add(aa);
ctx.SaveChanges();
}
EntityBs EntityBId | 姓名 | 实体 ID | 鉴别器 | EntityA_EntityAId 1 | 测试_BB_01 | 0 | 实体BB | 1
EntityAs EntityAId | 姓名 | 鉴别器 1 | 测试_AA_01 | 实体AA
现在还有一个我无法访问的额外 ForeignKeyColumn 以及一个额外的鉴别器列。
有人知道该怎么做才能使其正常工作吗?如有必要,我已准备好将项目邮寄/附加。
亲切的问候,
斯文