我目前正在清理一個相當大的數據庫的過程。部分數據庫的關係是一對一或一對映射。具體來說:映射一對零或一與EF7
User -> UserSettings
並非所有用戶都有用戶設置,但用戶設置不能在沒有用戶的情況下存在。不幸的是,表格已經存在。 User
有一個PK ID。 UserSettings
有一個PK ID和一列,User_Id_Fk
,在這個時間點上,它不是一個真正的FK(沒有定義關係)。
我正在修復這個問題,並且已經從數據庫角度通過SQL完成了這些工作,並已通過測試進行了確認。 (增加了FK約束,在User_Id_Fk
上增加了一個唯一約束)。這一切都在UserSettings
表上完成。 (注意:這裏我沒有使用EF遷移,現在我必須手動編寫SQL)。
但是,我現在需要連接現有的應用程序以正確處理這個新的映射。該應用程序使用ASP.NET Core 1.0和EF7。以下是現有數據模型的(縮短的)版本。
public class User
{
public int Id { get; set; }
public virtual UserSettings UserSettings { get; set; }
}
public class UserSettings
{
public int Id { get; set; }
[Column("User_Id_Fk")]
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
}
我有這種良好的映射,以及:
builder.Entity<UserSettings>()
.HasOne(us => us.User)
.WithOne(u => u.User)
.IsRequired(false);
當我去運行應用程序和訪問數據庫中的這些項目,我得到遵循的神祕的一組消息有此錯誤與直接回我的應用程序:
ArgumentNullException: Value cannot be null.
Parameter name: navigation
Microsoft.Data.Entity.Utilities.Check.NotNull[T] (Microsoft.Data.Entity.Utilities.T value, System.String parameterName) <0x10d28a650 + 0x00081> in <filename unknown>, line 0
做研究後沒有任何信息,有人提到,UserSettings類的ID必須是相同的外鍵,LIK è這樣:
public class UserSettings
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public virtual User User { get; set; }
}
我真的沒有這個作爲一個選項,正在使用的數據塊是我無法控制的在這一點上的其他應用程序。那麼,我在這裏?我只需要維持一個1:多的映射(其中可能是現在雖然沒有),但對於1:0..1映射沒有適當的約束?
更新 看看下面的octavioccl的答案,我試了一下沒有任何成功。不過,我然後從UserSettings
(但我離開UserId
)的映射中刪除User
。據我所知,一切似乎都奏效。但是,我真的很困惑這裏發生了什麼,如果這是正確的答案,或者我只是幸運的話。
感謝您的回覆。不幸的是,沒有去。我對你的答案有點困惑,用戶應該只有零個或一個UserSetting。我不瞭解你的解決方案如何實現這一點。 (這超出了我仍然收到相同錯誤的事實。)您能否提供澄清?謝謝! – JasCav
添加了編輯/更新。 – JasCav
我現在看到你的更新了,我認爲它的效果很好,因爲EF認爲你現在的關係是一對多而不是一對一的關係。當你在相關實體之間聲明一個導航屬性時,默認情況下EF創建一對多,我也混淆了你當前模型的工作方式,因爲如果你在'UserSettings'表中有FK列,如果EF看到一對多,集合導航屬性應該在'User'中聲明,而不是參考導航屬性。確實很迷惑,讓我再想想整個一遍,如果我找到更合理的我要讓你知道 – octavioccl