3

我使用實體框架6.0.2在其標籤存儲在一個單一的表,看起來像這樣一個現有的數據庫:EF6 - 使用基類屬性派生類TPH外鍵映射

  • Id:整型,主鍵
  • TagType:串,確定標籤的類型,無論是「usertag」或「movietag」
  • ItemId:整數,包含該項目的ID被稱爲(或者用戶ID或一個電影Id)

下面的類描述了這種情況:

public class User 
{ 
    public int Id { get; set; } 
} 

public class Movie 
{ 
    public int Id { get; set; } 
} 

public abstract class Tag 
{ 
    public int Id { get; set; } 
    public int ItemId { get; set; } 
} 

public class UserTag : Tag 
{ 
    public virtual User User { get; set; } 
} 

public class MovieTag : Tag 
{ 
    public virtual Movie Movie { get; set; } 
} 

正如你可以看到我的派生類具有導航性能,這是通過在基類中的ItemId財產的價值提供支持。我的映射如下:

public class Context : DbContext 
{ 
    public DbSet<Tag> Tags { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Tag>() 
      .Map<UserTag>(m => m.Requires("TagType").HasValue("usertag")) 
      .Map<MovieTag>(m => m.Requires("TagType").HasValue("movietag")); 

     modelBuilder.Entity<UserTag>() 
      .HasRequired(m => m.User).WithMany().HasForeignKey(m => m.ItemId); 

     modelBuilder.Entity<MovieTag>() 
      .HasRequired(m => m.Movie).WithMany().HasForeignKey(m => m.ItemId); 
    } 
} 

現在,當我嘗試使用下面的代碼使用此對應關係,我得到一個異常:

using System.Data.Entity; 

class Program 
{ 
    static void Main() 
    { 
     using (var db = new Context()) 
     { 
      db.Database.Delete(); 
      db.Database.Initialize(false); 
     } 
    } 
} 

的異常被拋出是:

Unhandled Exception: System.InvalidOperationException: The foreign key component 'ItemId' is not a declared property on type 'UserTag'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property

是的ItemId屬性沒有在類型UserTag上聲明,但它是從基地繼承的類。對我來說,似乎這個映射應該是可能的。這是實體框架6中的錯誤還是限制?

回答

4

這是一個限制。 EF與關係數據庫的工作方式緊密相關。你試圖在數據庫方面做的是在單個ItemId列上放置兩個外鍵約束。數據庫中的外部約束不是有條件的,因此無論標記類型如何,記錄都將始終使用兩個約束。這不是你想要的,因爲這樣的定義總是要求用戶和具有特定Id的電影存在於每個標籤中。

用不同的方式思考它。如果它的工作方式如何試圖定義它,那麼沒有理由在子實體中擁有UserMovie導航屬性 - 在父項中具有單個導航屬性就足夠了。事實上,你必須在子實體中定義它們,因爲它們對於每個實體都是不同的,這也意味着你需要有兩個不同的外鍵。

您需要在其特定標籤中單獨使用UserIdMovieId

+0

我明白了。要嘗試解決方案,請在已移動的特定標記類中添加UserId和MovieId屬性。但是,現在我得到以下錯誤:ItemId::沒有名稱'ItemId'的屬性在角色'Tag'中引用的類型中定義。有關我所嘗試的內容,請參閱:https://gist.github.com/ErikSchierboom/8253705 –