整個錯誤:
外鍵屬性“Appointment.CustomerId1”是在影子狀態下創建的,因為物體型別中存在具有簡單名稱“CustomerId”的沖突屬性,但未映射、已用于其他關系或與關聯的主鍵型別。
表:
預約
用戶
在 Appointment 表中,我有 2 個 FK:一個指向 Customer 表(Id 列),另一個指向 Employee 表(Id 列)。請參閱“之前”部分的圖片。但是現在,因為我將所有用戶(客戶 員工)放在同一個用戶表中,所以它必須改變。這意味著在 Appointment 表中我需要有 2 個 FK,但都需要指向同一個表 User 和 Id 列。我希望 CustomerId 和 EmployeeId 指向用戶的 Id。
它創建了 3 個額外的列:UserId、CustomerId1 和 EmployeeId1——這是我不想要的。我只對關系使用約定,沒有使用資料注釋或 Fluent API。
有 3 種情況會導致錯誤:
-
- 未映射
-
- 已經用于另一種關系
-
- 與關聯的主鍵型別不兼容
據我了解
-
- 不是我的情況,因為資料型別是相同的(字串)。
-
- 不是我的情況,因為我沒有其他關系。
-
- 可能有問題,但我不確定。我可能需要為此映射添加一些 Fluent Api。這是我嘗試過的方法,但沒有用: https ://i.stack.imgur.com/UFrC6.png
雙向方法:
用戶類:
public ICollection<Appointment> AppointmentCustomers { get; set; }
public ICollection<Appointment> AppointmentEmployees { get; set; }
預約類:
public string CustomerId { get; set; }
[ForeignKey("CustomerId")]
public User Customer { get; set; }
public string EmployeeId { get; set; }
[ForeignKey("EmployeeId")]
public User Employee { get; set; }
OnModelCreating方法:
builder.Entity<Appointment>()
.HasOne(u => u.Customer)
.WithMany(app => app.AppointmentCustomers)
.HasForeignKey(u => u.CustomerId)
.OnDelete(DeleteBehavior.NoAction);
builder.Entity<Appointment>()
.HasOne(u => u.Employee)
.WithMany(app => app.AppointmentEmployees)
.HasForeignKey(u => u.EmployeeId)
.OnDelete(DeleteBehavior.NoAction);
uj5u.com熱心網友回復:
以前,EF 可以按照約定計算出密鑰。約定基于型別名稱(員工與客戶)而不是變數名稱。如果您將 FKs EmployeeKey/EmpID 和 CustomerKey/CustID 命名為您會遇到類似的問題。EF 的約定不會將它們關聯為 FK,因此它會創建影子屬性。
現在您將它們指向同一型別(用戶)EF 不能使用約定,因此您必須明確。解決這個問題的最簡單方法是使用[ForeignKey]屬性。這可以放在 FK 屬性上以指向導航屬性,也可以放在導航屬性上以指向 FK。
IE
[ForeignKey(nameof(Customer))]
public string CustomerId { get; set; }
[ForeignKey(nameof(Employee))]
public string EmployeeId { get; set; }
public virtual User Customer { get; set; }
public virtual User Employee { get; set; }
或者
public string CustomerId { get; set; }
public string EmployeeId { get; set; }
[ForeignKey(nameof(CustomerId))]
public virtual User Customer { get; set; }
[ForeignKey(nameof(EmployeeId))]
public virtual User Employee { get; set; }
編輯:
您現在遇到的錯誤是因為 User 有一個 Appointments 集合,但您必須告訴 EF 此 FK 鏈接到哪個集合。這里有一個約會,它參考了兩個用戶,一個客戶和一個員工。從用戶的角度來看,有兩種不同的關系。約會-我是客戶和約會-我是員工。
如果您只對一種關系感興趣,則需要配置 EF 以根據約會客戶或員工關系映射 User.Appointments。如果您對兩者都感興趣,那么您有兩種選擇。
a) 向用戶添加 2 個約會集合,即 AppointmentsAsCustomer 和 AppointmentsAsEmployee,并在 ModelBuilder 或 EntityTypeConfiguration 中設定映射。b) 洗掉 User 上的 Appointments 集合并使用 a 配置 EF,.HasOne(x => x.Customer).WithMany()然后.HasOne(x => x.Employee).WithMany()當您想要查詢用戶的約會時,從 Appointments 中執行,而不是期望通過 User 導航:
代替:
var appointmentsForUser = context.Users
.Where(u => u.UserId == userId)
.SelectMany(u => u.Appointments) // can't work for both asEmployee and asCustomer
.ToList();
利用:
var appointmentsForUser = context.Appointments
.Where(a => a.Customer.UserId == userId
|| a.Employee.UserId == userId) // if you want appts where user is customer or employee
.ToList();
雙向參考(其中 Apointments 參考了用戶,而 User 參考了 Appointments)應該僅在絕對需要時謹慎使用,而不是默認使用。它們在更新時可能會導致奇怪的行為加上延遲加載的影響,以及像這樣具有模棱兩可的關系的“陷阱”。
uj5u.com熱心網友回復:
該屬性已用于舊 Customer 和 Employee 類的另一個關系。
(Steve Py 的回答對外鍵配置有很大幫助,但從我讀到的內容來看,通過 Fluent API 與資料注釋配置它們更好。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/537640.html
上一篇:在物體框架中為ICollectionofbookings定義回圈關系
下一篇:DateTime末尾的零
