2

真的會很感激一點關於如何在我自己的MVC5自定義類中使用ApplicationUser的指導。MVC5實體框架代碼第一次錯誤創建數據庫當使用ApplicationUser

簡單模型,使用腳手架創建控制器和視圖,從Internet應用程序模板的默認ApplicationUser(IdentityUser)sm DbContext。我想使用ApplicationUser來爲交易添加當時登錄的人員的詳細信息。

我得到兩個數據庫錯誤之一,當實體框架試圖DropAndRecreateAlways

一是我的課:

public class Example 
{ 
    public int ID { get; set; } 

    [Required] 
    public string Description { get; set; } 

    [Required] 
    public double Amount { get; set; } 

    [Required] 
    public virtual ApplicationUser CreatedBy {get; set;} 

    [Required] 
    public virtual ApplicationUser ModifiedBy { get; set; } 
} 

錯誤,我得到當實體框架試圖創建數據庫中:

  1. {「模型生成過程中檢測到一個或多個驗證錯誤:\ r \ n \ r \ nMvcApplication1.Models.IdentityUserLogin :: EntityType'IdentityUserLogin'has no ke y定義。定義此EntityType的密鑰。\ r \ nMvcApplication1.Models.IdentityUserRole :: EntityType'IdentityUserRole'沒有定義密鑰。 \ r \ nIdentityUserLogins:EntityType:EntitySet'IdentityUserLogin'基於'IdentityUserLogin'類型,沒有定義鍵。\ r \ nIdentityUserRoles:EntityType:EntitySet'IdentityUserRoles'基於'IdentityUserRole'類型。有沒有鍵定義。\ r \ n「}

  2. 參照完整性由於梯級上刪除(我可以覆蓋的DbContext刪除級聯刪除)

什麼是實現這一目標的最佳途徑?任何指導將不勝感激。

+0

你可以提供IdentityUserLogin,IdentityUserRole和DbContext的代碼嗎? – bdparrish

+0

我認爲這是一個上下文相關的問題。我猜你有兩個上下文。嘗試合併兩者。 –

+0

MVC5默認的Internet應用程序創建ApplicationUser,它繼承自包含IdentityUserLogin和IdentityUserRole的IdentityUser,這些對我的項目不可見。 –

回答

0

我決定發佈一個可行的答案,但我仍然不相信它是最乾淨的答案,並且很想聽聽有沒有人有更好的方法來做到這一點。

我得到這個工作的答案是覆蓋OnModelCreating()ApplicationDbContext: IdentityDbContext並用流利的API來的IdentityUserLoginIdentityUserRole屬性標記爲[Key]

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

     modelBuilder.Entity<IdentityUserLogin>().HasKey(t => t.UserId); 
     modelBuilder.Entity<IdentityUserRole>().HasKey(t => t.UserId); 

    } 

我不認爲這是一個很好的解決方案因爲EF Code First現在在我的IdentityUserLoginIdentityUserRole表格中創建了兩列,UserIdUser_Id

這會做現在。建議非常受歡迎。

0

它正在尋找[Key]附加說明n爲您的實體。看起來你缺少一個兩個IdentityUserLoginIdentityUserRole

public class Person 
{ 
    [Key] // <--- this needs to be identified here or in the DbContext you setup 
    public Guid ID { get; set; } 
} 
+1

通過EF約定Id或ID是主鍵。不需要明確指定。 –

+0

潛在的,但是IdentityUserLogin和IdentityUserRole是由ApplicationUser創建的類,因爲它繼承了IdentityUser的形式,我如何將Key屬性添加到IdentityUserLogin和IdentityUser角色以及爲什麼Microsoft不默認使用[Key]對它們進行註釋? –

0

兩個建議:

1 - 確保您的DbContext從IdentityDbContext派生。

2 - 根據您的模型,您有用戶和其他實體之間的關係。你的dbcontext DBSet語句是怎麼看的?你有用戶的dbset嗎? (這意味着你假設用戶的管理而不是IdentityFramework)。如果您的用戶沒有DBSet,那麼我會同意Ashish的說法,身份實體的環境可能與您的其他實體的環境不同,這會產生問題。

如果你可以發表你的上下文類的基本知識,我們也許能夠告訴更多

+0

謝謝,我使用了兩個DbContext,一個是使用MVC5 Internet應用程序創建的,默認情況下從IdentityDbContext繼承,如同第一點,另一個是通過從標準DbContext繼承的腳手架創建的。只有改變了我向嚮導創建的上下文,才能將它們指向相同的DefaultConnectionString,以便所有表都在同一個數據庫中。 EF Code First一次僅使用一個上下文創建數據庫嗎?如果是這樣,那麼這可能是數據庫創建一點點的答案。 –

+0

爲我的整個應用程序使用ApplicationDbContext:IdentityDbContext是否糟糕的體系結構? –

+0

我將從第二個問題開始。使用ApplicationDbContext:IdentityDbContext並不是糟糕的體系結構。 IdentityDbContext只是一個更加專業化的派生類,它增加了對身份的支持,如果你的dbcontext不是從IdentityDbContext派生的,你會遇到更多你還沒有的問題,我保證。 (一旦你開始將實體連接到用戶並更新用戶) – freud

1

我建議你到你ID[Key]屬性註釋。 根據您發佈的第一個錯誤,EF目前無法找到表Example的主鍵。另外,如果您以後需要延遲加載CreatedByModifiedBy,那麼您也需要提到Id,儘管現在這不是錯誤。未來可能很容易。

除此之外,還從IdentityUser類,然後從IdentityDbContextDbContext類繼承您的ApplicationUser類。

清理項目,重建它並查看是否發生錯誤。那麼解決它可能會更容易。

+1

我以爲EF Code First可以自動識別[Key]如果您將屬性命名爲ID? ApplicationUser已經從IdentityUser繼承,我的一個上下文繼承自IdentityDbContext(另一個來自DbContext) –

2

你的問題是,你忘了打電話給

base.OnModelCreating(modelBuilder); 

在頂過你的方法,因爲像你說的ApplicationDbContext默認情況下,從IdentityDbContext繼承創建。所以調用base.OnModelCreating,讓你的基類即IdentityDbContext,生成你所需要的一切。

但是如果你還是想用流利的API,用於創建兩個實體按鍵的正確的方法是

modelBuilder.Entity<IdentityUserLogin>().HasKey(t => new { t.UserId, t.ProviderKey, t.LoginProvider }); 
modelBuilder.Entity<IdentityUserRole>().HasKey(t => new { t.RoleId, t.UserId }); 

沒有這樣做,調用AddToRole(用戶ID,角色名)的UserManager的方法將拋出一個需要額外添加密鑰的例外消息「字段UserId或RoleId是必需的」。

相關問題