![](/img/trans.png)
[英]Entity Framework - Code first - Data annotations - Unnecessary foreign key columns
[英]Can I create a bidirectional foreign key relationship using Entity Framework Code First data annotations?
我正在使用EF 6 Code First,並試圖找出使用數據批注配置我的關系的最佳方法,但是由於某些原因,EF向我不需要的架構添加了額外的列。
我有兩個實體: Ship
和Voyage
。 一艘船可以航行很多次。 一次航行屬於一艘並且只有一艘船。 因此,我從這里開始(出於SO的目的而簡化):
public class Ship
{
public int Id { get; set; }
public virtual ICollection<Voyage> Voyages { get; set; }
}
public class Voyage
{
public int Id { get; set; }
public int ShipId { get; set; }
public virtual Ship Ship { get; set; }
public DateTimeOffset Started { get; set; }
}
這將在數據庫中創建兩個表,如下所示:
CREATE TABLE [dbo].[Ship] (
[Id] INT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_dbo.Ship] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Voyage] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[ShipId] INT NOT NULL,
[Started] DATETIMEOFFSET (7) NOT NULL,
CONSTRAINT [PK_dbo.Voyage] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Voyage_dbo.Ship_ShipId] FOREIGN KEY ([ShipId]) REFERENCES [dbo].[Ship] ([Id]) ON DELETE CASCADE
);
到現在為止還挺好。 問題出在我要查詢此數據時。 我需要獲取船只清單,但對於每艘船只,我也希望最近一次航行。 即使我能夠使用SQL編寫這樣的查詢,我也看不出一種可以一口氣做到這一點的LINQ查詢的方法。
在這一點上,我的選擇似乎是:
foreach
結果列表,並對每個船只執行單獨的查詢以加載其“最近”航行。 盡管此方法有效,但與單個查詢相比似乎效率低下。 然后我以為可以將導航屬性添加到Ship
實體,該實體將用於直接引用“最新”航程。 所以我嘗試了這個:
public class Ship
{
public int Id { get; set; }
public virtual ICollection<Voyage> Voyages { get; set; }
public int? MostRecentVoyageId { get; set; } <-- new property added
public virtual Voyage MostRecentVoyage { get; set; } <-- new property added
}
我將MostRecentVoyageId
可空,因為船舶在首次創建時將完全沒有任何航程。
這為我提供了數據庫中的以下內容:
CREATE TABLE [dbo].[Ship] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[MostRecentVoyageId] INT NULL,
CONSTRAINT [PK_dbo.Ship] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Ship_dbo.Voyage_MostRecentVoyageId] FOREIGN KEY ([MostRecentVoyageId]) REFERENCES [dbo].[Voyage] ([Id])
);
這對於Ship
表來說很好,但是對於Voyage
表我可以做到這一點:
CREATE TABLE [dbo].[Voyage] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[ShipId] INT NOT NULL,
[Started] DATETIMEOFFSET (7) NOT NULL,
[Ship_Id] INT NULL,
CONSTRAINT [PK_dbo.Voyage] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Voyage_dbo.Ship_ShipId] FOREIGN KEY ([ShipId]) REFERENCES [dbo].[Ship] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Voyage_dbo.Ship_Ship_Id] FOREIGN KEY ([Ship_Id]) REFERENCES [dbo].[Ship] ([Id])
);
請注意額外的Ship_Id
列和額外的外鍵關系。 我可以肯定不需要此專欄,但是我找不到擺脫它的方法。 我已經嘗試過使用[ForeignKey]
和[InverseProperty]
屬性,但是這些只是給我一個例外。
我無法使用EF數據注釋配置這種關系嗎? 為此,我是否必須使用流利的語法? 無論如何,我是否都做錯了:是否有更好的方法使用原始實體類型來進行LINQ查詢?
我有幾乎完全相同的模型,但是在不同的上下文中,並且通過將[ForeignKey("MostRecentVoyage")]
屬性添加到MostRecentVoyageId
並添加[InverseProperty("Ship")]
擺脫了數據庫中不需要的列都在Ship
實體/類上同時具有Voyages
屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.