[英]Entity Framework - Fluent API Mapping
public class Customer
{
public int Id { get; set; }
public int AddressId { get; set; }
public virtual Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public virtual Customer { get; set; }
}
客戶必須強制提供一個地址。 一個地址可能有也可能沒有客戶。 地址中的“客戶”導航屬性類似於“可為空”。 我在Customer.AddressId表中具有唯一索引。
有什么方法可以使用流暢的API進行此映射?
編輯:
CREATE TABLE Address
(
Id INT NOT NULL IDENTITY PRIMARY KEY,
AddressLine1 VARCHAR(50),
)
CREATE TABLE Customer
(
Id INT NOT NULL IDENTITY PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
AddressId INT NOT NULL,
CONSTRAINT FK_Customer_Address FOREIGN KEY(AddressId) REFERENCES Address (Id)
)
我重新創建了整個數據庫和模型,並且能夠將記錄添加到客戶表和地址表中。
基本上,如果一個客戶可以只有一個地址,那么這意味着一個地址可以有0個或多個客戶。 (不是0或1)理想。 但是由於您的唯一性限制,該地址總是以0或1個客戶記錄結尾。 但這是一個運行時約束,EF在設計時不知道這一點。 (我認為它不能完全掌握2向關系的唯一性規則)EF將“客戶對客戶”模型建模為0:N,並讓運行時處理N永遠不會大於1的事實。
這是因為想到了記錄。
因此,AddressA有1個客戶記錄,AddressD有0個客戶記錄。
現在的問題是,您的SQL Server知道一個客戶記錄只能有一個地址記錄, 並且該地址記錄必須是唯一的。
EF無法雙向理解唯一性部分。 它知道客戶只需要一個地址,但不能強制要求該地址必須唯一。 如果基礎INSERT如果您嘗試插入一個地址已經屬於另一個客戶的客戶,則該錯誤自然會發生。 由於唯一性的限制,EF實際上在創建一個模型方面做得很好,客戶與地址之間的比例為1:1。
但是因為它不能雙向理解唯一性部分,所以它將多個客戶映射到一個地址。 (0個或更多的客戶,而不是0或1)
因此,您的映射需要如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>()
.HasMany(e => e.Customers)
.WithRequired(e => e.Address)
.WillCascadeOnDelete(false);
}
這樣可以確保客戶始終具有所需的地址實體,並且一個地址具有0個或更多客戶。 (在實踐中,由於唯一性約束,在該列表中始終只能得到0或1個客戶),但不能在EF中強制實施。 您需要始終獲取List<Customers>
並且它將始終具有0或1個元素。
如果您嘗試手動修改映射,並在地址和客戶之間具有可選的0:1關系(而不是0:N),則EF會有些困惑,並由於某種原因開始引發IDENTITY插入異常。 不知道為什么。
因此您可以使用上述映射,並確保List<Customers>
始終只有0或1條記錄
提出了一些功能要求,以從兩方面完全理解唯一性方面(我認為這轉化為很好理解的關系代數)。 https://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/1050579-unique-constraint-ie-candidate-key-support
public class Customer
{
public int Id { get; set; }
public Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public int? CustomerId { get; set; }
public virtual Customer { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.