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-method の理由である異なるコンテキストにある可能性があることに注意してください。
今、私はこのようなコンテキストを結合したいと思います:
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 | EntityBs 名前 | EntityAId | 弁別器 | EntityA_EntityAId 1 | Test_BB_01 | 0 | エンティティBB | 1
EntityAs EntityAId | 名前 | 弁別器 1 | Test_AA_01 | エンティティAA
これで、アクセスできない追加の ForeignKeyColumn と、追加の識別子列があります。
誰かがこれを機能させるために何をすべきか考えていますか? 必要に応じてプロジェクトをメール/添付する準備ができています。
敬具、
スヴェン