![](/img/trans.png)
[英]Entity framework WithRequired fluent api to data annotations mapping
[英]Entity Framework : Invalid column name *_ID even with fluent api or data annotations
我整天都在看的奇怪問題。 我正在使用 Entity Framework 6。我遇到的問題是我有三個實體:
public partial class Order : ILocationBearingObject
{
public int Id { get; set; }
// other properties and relationships here
public int? OrderProfileId { get; set; }
public int OrderTemplateId { get; set; }
public virtual OrderProfile Profile { get; set; } // optional property
public virtual OrderTemplate OrderTemplate{ get; set; }
}
public class OrderProfile
{
public int Id { get; set; }
// other properties
// added here 6/15/2021
public virtual OrderTemplate OrderTemplate{ get; set; }
}
public class OrderTemplate : EntityMetaData
{
public int Id { get; set; }
// other properties
public int? OrderProfileId{ get; set; }
public OrderProfile OrderProfile { get; set; }
}
在我們的 model 構建器中,我們有以下定義:
modelBuilder.Entity<Order>()
.HasOptional(x => x.OrderProfile)
.WithMany(x => x.Orders)
.HasForeignKey(x => x.OrderProfileId);
modelBuilder.Entity<OrderProfile>()
.HasOptional(x => x.OrderTemplate)
.WithOptionalPrincipal(x => x.OrderProfile);
但即使使用上述流暢的 api model,我們也會得到錯誤
列名“OrderProfile_Id”無效
在各種測試中,我無法找到為什么會出現這個問題,所以我查看了我們的日志,發現這個錯誤什么時候開始出現,然后能夠找到與 OrderProfile 關聯的更改,發現唯一的更改是正在添加從 OrderProfile 到 OrderTemplate 的關系。
當我刪除流利的 api 關系 OrderProfile 到 OrderTemplate 時,它按預期工作......我不需要與 OrderTemplate 的關系,但希望它在那里,我怎樣才能在不破壞其他關系的情況下建立可選的 1 到可選的 1 關系關系? 另外,為什么會影響其他關系?
更新 6/15/2021所以我發現我在 OrderProfile model 中有一個反向導航屬性:
public virtual OrderTemplate OrderTemplate{ get; set; }
刪除那個和相關的流暢關系
modelBuilder.Entity<OrderProfile>()
.HasOptional(x => x.OrderTemplate)
.WithOptionalPrincipal(x => x.OrderProfile);
執行上述操作解決了該問題,但由於某種原因,該問題似乎已經級聯到另一個具有上述循環引用的關系。 此級聯問題涉及訂單 class。 我想這是一個非常令人擔憂的原因,因為這個應用程序在過去 4 年里運行良好,而且這些關系像這樣衰減是令人擔憂的。 有誰知道為什么會這樣?
如果您使用正確的命名約定,EF 將發揮作用。 在此示例中,您不需要流利的 API 來關聯實體。
public partial class Order : ILocationBearingObject
{
public int Id { get; set; }
public int? OrderProfileId { get; set; } //means HasOptional (nullable) and ForeignKey
//variable name must be OrderProfile not Profile
public virtual OrderProfile OrderProfile { get; set; }
}
public class OrderProfile
{
public OrderProfile()
{
Orders = new HashSet<Order>();
}
public int Id { get; set; }
//be aware circular reference at any conversion or mapping
public virtual ICollection<Order> Orders {get; set;} //means WithMany
}
我也有這樣的錯誤。 這是由於 OrderTemplate class 中的 OrderProfileId 屬性與流利的 api model 不匹配引起的
如果我沒記錯的話,您希望 OrderProfile model 是 Order 和 OrderTemplate 之間的多對多關系。 然后,如果是這種情況,請在 OrderProfile 中添加 nvaigation 屬性。
public class OrderProfile
{
public int Id { get; set; }
// other properties
public virtual ICollection<Order> Orders { get; set; }
public virtual OrderTemplate OrderTemplate { get; set; }
}
然后把fluent api model改成這樣
// the EF has modelled the relation for normal 1 to many relation
// modelBuilder.Entity<Order>()
// .HasOptional(x => x.OrderProfile)
// .WithMany(x => x.Orders)
// .HasForeignKey(x => x.OrderProfileId);
modelBuilder.Entity<OrderTemplate>()
.HasOptional(x => x.OrderProfile)
.WithOptional(x => x.OrderTemplate);
您首先使用數據庫,這總是為實際數據庫 model 和 model EF 從 class 和屬性名稱和映射代碼推斷出的不匹配留出空間。 如果發生這種情況,它可能有助於使 EF 從概念 model 生成數據庫,並查看它在哪里創建它期望的列OrderProfile_Id
。
這是您在記錄 SQL 語句時將看到的內容:
CREATE TABLE [dbo].[OrderTemplates] (
[Id] [int] NOT NULL IDENTITY,
[OrderProfileId] [int],
[OrderProfile_Id] [int],
CONSTRAINT [PK_dbo.OrderTemplates] PRIMARY KEY ([Id])
)
...
ALTER TABLE [dbo].[OrderTemplates]
ADD CONSTRAINT [FK_dbo.OrderTemplates_dbo.OrderProfiles_OrderProfile_Id]
FOREIGN KEY ([OrderProfile_Id]) REFERENCES [dbo].[OrderProfiles] ([Id])
在那里,您會看到預期的可為空列OrderProfile_Id
,它是OrderProfiles
的 FK。 值得注意的是,EF不使用OrderProfileId
作為外鍵字段。 它只是一個可以用於任何事情的字段。
這是因為 EF6 不支持 1:1 關聯作為外鍵關聯(引用屬性和原始 FK 屬性)。
知道了這一點,補救措施很簡單:刪除屬性OrderTemplate.OrderProfileId
並告訴 EF 使用數據庫中的字段OrderTemplate.OrderProfileId
:
modelBuilder.Entity<OrderProfile>()
.HasOptional(x => x.OrderTemplate)
.WithOptionalPrincipal(x => x.OrderProfile)
.Map(m => m.MapKey("OrderProfileId"));
也就是說,我想知道為什么Order
有OrderProfile
的外鍵。 它的OrderProfile
不是由它的OrderTemplate
決定的嗎? 如果它是冗余關系,最好將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.