我有一个关于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 |名称| EntityAId |鉴别者| EntityA_EntityAId 1 | Test_BB_01 | 0 | EntityBB | 1
EntityAs EntityAId |名称| Disciminator 1 | Test_AA_01 | EntityAA
现在还有一个我无法访问的额外ForeignKeyColumn以及一个额外的鉴别器列。
有人知道该怎么做,让这个工作吗?我有项目准备好在必要时邮寄/附加它。
亲切的问候,
斯文