所以,我有兩個主要對象,Member和Guild。一個會員可以擁有一個協會,一個協會可以擁有多個會員。不同DbContext和不同模式之間的實體框架關係
我有一個單獨的DbContext和單獨的類庫中的成員類。我打算在多個項目中重用這個類庫並幫助區分,我將數據庫模式設置爲「acc」。我已經廣泛地測試了這個庫,並且可以在acc.Members表中添加,刪除和更新成員。
公會類是這樣的:
public class Guild
{
public Guild()
{
Members = new List<Member>();
}
public int ID { get; set; }
public int MemberID { get; set; }
public virtual Member LeaderMemberInfo { get; set; }
public string Name { get; set; }
public virtual List<Member> Members { get; set; }
}
用的映射:
internal class GuildMapping : EntityTypeConfiguration<Guild>
{
public GuildMapping()
{
this.ToTable("Guilds", "dbo");
this.HasKey(t => t.ID);
this.Property(t => t.MemberID);
this.HasRequired(t => t.LeaderMemberInfo).WithMany().HasForeignKey(t => t.MemberID);
this.Property(t => t.Name);
this.HasMany(t => t.Members).WithMany()
.Map(t =>
{
t.ToTable("GuildsMembers", "dbo");
t.MapLeftKey("GuildID");
t.MapRightKey("MemberID");
});
}
}
但是,當我嘗試創建一個新的公會,它說,沒有dbo.Members 。
我得到了成員的EF項目的引用,並將成員類的映射添加到了Guild類所屬的DbContext中。 modelBuilder.Configurations.Add(new MemberMapping());
這導致這個錯誤(不知道這是最好的方式。):
{"The member with identity 'GuildProj.Data.EF.Guild_Members' does not exist in the metadata collection.\r\nParameter name: identity"}
我如何可以利用這兩個表交叉DbContexts之間和不同的數據庫模式外鍵?
UPDATE
我縮小了錯誤的原因。當我創建一個新公會時,我將公會領導的會員ID設置爲MemberID。這工作正常。但是,當我嘗試將該領導的會員對象添加到會員(會員)的協會名單時,這就是導致錯誤的原因。
更新2
下面是如何創建的背景下,行業協會類是在代碼中。(根據要求由侯賽因·哈利勒)
public class FSEntities : DbContext
{
public FSEntities()
{
this.Configuration.LazyLoadingEnabled = false;
Database.SetInitializer<FSEntities>(null);
}
public FSEntities(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new GuildMapping());
modelBuilder.Configurations.Add(new KeyValueMappings());
modelBuilder.Configurations.Add(new LocaleMappings());
modelBuilder.Configurations.Add(new MemberMapping());
}
public DbSet<Guild> Guilds { get; set; }
public DbSet<KeyValue> KeyValues { get; set; }
public DbSet<Locale> Locales { get; set; }
}
這是我現在的儲蓄它在回購:
public async Task CreateGuildAsync(Guild guild)
{
using (var context = new FSEntities(_ConnectionString))
{
context.Entry(guild.Members).State = EntityState.Unchanged;
context.Entry(guild).State = EntityState.Added;
await context.SaveChangesAsync();
}
}
最終解決
所以,我不得不在DbContext中添加映射到Member
,Role
和Permission
,其中包含Guild
。我必須添加角色和權限,因爲成員有List<Role> Roles
,每個角色有List<Permission> Permissions
。
這讓我更接近解決方案。我仍然得到這樣的錯誤:
{"The member with identity 'GuildProj.Data.EF.Member_Roles' does not exist in the metadata collection.\r\nParameter name: identity"}
在這裏,當你從Session
拉會員,你得到的東西是這樣的:
System.Data.Entity.DynamicProxies.Member_FF4FDE3888B129E1538B25850A445893D7C49F878D3CD40103BA1A4813EB514C
實體框架似乎不玩這個很好。爲什麼?我不確定,但我認爲這是因爲ContextM創建了成員代理,並且通過將成員克隆到新成員對象中,ContextM不再具有關聯。我認爲,這允許ContextG自由使用新的成員對象。我嘗試在我的DbContexts中設置ProxyCreationEnabled = false,但從Session中退出的Member對象保持爲System.Data.Entity.DynamicProxies.Member類型。
所以,我所做的就是:
Member member = new Member((Member)Session[Constants.UserSession]);
我不得不克隆每個Role
每個Permission
以及內部的各自的構造函數。
這讓我有99%的出路。我不得不改變我的回購和我如何保存Guild
對象。
context.Entry(guild.LeaderMemberInfo).State = EntityState.Unchanged;
foreach(var member in guild.Members)
{
context.Entry(member).State = EntityState.Unchanged;
}
context.Entry(guild).State = EntityState.Added;
await context.SaveChangesAsync();
使用相同的「成員」類是不可能的?上下文之間的映射會有所不同,並且「成員」對象不能在上下文之間傳輸,而不會脫離第一個上下文,但似乎可能。 – jjj
@jjj是的,但我認爲'會員'將有其他協會,不應該被映射。如果'Member'是一個POCO並且映射是通過流暢的映射,那麼應該可以通過明確地將導航屬性保持未映射。但是我認爲在一個應用程序中有'Member'對象可以通過不同的上下文來實現是令人困惑的。 –
成員類型的屬性GuildLeader正確保存到數據庫沒有意義,但列表屬性不起作用。兩者都只保存一個ID。 –
ScubaSteve