2012-06-20 48 views
4

我在實體框架中定義外鍵關係時遇到問題。我已經將代碼編寫到最低限度來演示問題。我的關係有什麼問題?兩個相關實體引用的公共實體

該模型被定義爲;

public class AccessControlList 
{ 
    [Key] public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class ManagedFile 
{ 
    [Key] public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual AccessControlList AccessControl { get; set; } 
} 

public class ManagedFolder 
{ 
    [Key] public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual AccessControlList AccessControl { get; set; } 
    public virtual ISet<ManagedFile> Files { get; private set; } 

    public ManagedFolder() 
    { 
     Files = new HashSet<ManagedFile>(); 
    } 
} 

所以基本上,我有一個單獨的AccessControl實體,可以由ManagedFile或ManagedFolder實體引用。

爲了確保外鍵添加到ManagedFile和ManagedFolder,我已經添加了以下流利的映射

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

     modelBuilder.Entity<ManagedFile>() 
        .HasRequired(mf => mf.AccessControl) 
        .WithRequiredDependent() 
        .Map(m => m.MapKey("AccessControlListId")); 


     modelBuilder.Entity<ManagedFolder>() 
        .HasRequired(mf => mf.AccessControl) 
        .WithRequiredDependent() 
        .Map(m => m.MapKey("AccessControlListId")); 

     base.OnModelCreating(modelBuilder); 
    } 

這將構建看起來正是我期望的那樣,在每個外鍵AccessControlListId數據庫ManagedFile和ManagedFolder。

Entity Framework Created Schema

這一切對我來說很好,但是當我嘗試插入一些數據,使用此代碼

using(var ctx = new MyContext()) 
{ 
    var mf = ctx.Folders.Add(new ManagedFolder {Name = "$/"}); 
    mf.AccessControl = new AccessControlList(); 

    var file = new ManagedFile {Name = "myfile.txt"}; 
    mf.Files.Add(file); 
    file.AccessControl = new AccessControlList(); 

    ctx.SaveChanges(); 
} 

它拋出一個錯誤...

Error

我搞不​​清楚我做了什麼不正確?

據我瞭解我的映射,EF可以保存一個新的AccessControlList實體,然後使用Id編寫ManagedFolder或ManagedFile表。

一如既往,我感謝提供的任何幫助。

感謝安迪

回答

5

爲什麼會出現數據庫查找「完全按你期望」?顯然你試圖定義兩個一對一的關係(.HasRequired(...).WithRequiredDependent(...)),但是你在數據庫中的關係是一對多的。

你想要一對一到一對多的關係嗎?在後一種情況下(這很容易),只需用WithMany()替換兩個WithRequiredDependent()方法即可。

如果你想要一對一的,你不能定義一個單獨的外鍵AccessControlListId。您必須使用共享主鍵,即相關聯的PK是FK。映射必須是:

modelBuilder.Entity<ManagedFile>() 
      .HasRequired(mf => mf.AccessControl) 
      .WithRequiredDependent(); 
// the same for ManagedFolder 

...沒有MapKey

+0

看起來不錯,是不是我所期望的,因爲數據庫模式允許共享AccessControlLists。我可以在代碼中確保它只會是1:1。所以.WithMany()修復了它,謝謝。 –