Entity Framework 6.1 - 单个实体上的代码优先一对多:无法将 PK 映射到 FK?
Entity Framework 6.1 - Code-First One-to-Many on single entity: Can't map PK to FK?
我正在尝试先使用代码在单个 table/entity 上执行一对多。我的实体看起来像这样并且工作正常:
public class StockIndex
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(45, MinimumLength = 3)]
public string Name { get; set; }
[StringLength(500)]
public string Description { get; set; }
public List<Component> Components { get; set; }
public StockIndex ParentStockIndex { get; set; }
public List<StockIndex> StockSubIndices { get; set; }
public StockIndex()
{
StockSubIndices = new List<StockIndex>();
}
}
它创建了一个 table 与 PK 和 FK,就像你期望的那样:
CREATE TABLE [dbo].[StockIndex] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (45) NULL,
[Description] NVARCHAR (500) NULL,
[ParentStockIndex_Id] INT NULL,
CONSTRAINT [PK_dbo.StockIndex] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.StockIndex_dbo.StockIndex_ParentStockIndex_Id] FOREIGN KEY ([ParentStockIndex_Id]) REFERENCES [dbo].[StockIndex] ([Id])
);
效果很好。我已经为它搭建了所有的 CRUD 并且一切正常。但是,这迫使我在进行编辑时在我的控制器中触发一个额外的查询,以便查找 "parent" 记录并将其分配给新记录。我想访问 table 中的 "ParentStockIndex_Id" 字段,因此我可以直接从下拉列表中分配它并跳过额外的查找查询。我尝试映射它:
public class StockIndex
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(45, MinimumLength = 3)]
public string Name { get; set; }
[StringLength(500)]
public string Description { get; set; }
public List<Component> Components { get; set; }
public int ParentStockIndex_Id { get; set; }
[ForeignKey("ParentStockIndex_Id")]
public StockIndex ParentStockIndex { get; set; }
public List<StockIndex> StockSubIndices { get; set; }
public StockIndex()
{
StockSubIndices = new List<StockIndex>();
}
}
但是当我的 DbContext 中播种数据时 运行 它出现异常:
无法确定 'MyApp.Models.StockIndex_ParentStockIndex' 关系的主体端。多个添加的实体可能具有相同的主键。
我确定我做错了什么,但如果可能的话,我想在不使用 Fluent 的情况下做到这一点。
您应该使用 public int? ParentStockIndex_Id { get; set; }
来设置不需要的 Parent(您看到 int 后面的问号了吗)。
我正在尝试先使用代码在单个 table/entity 上执行一对多。我的实体看起来像这样并且工作正常:
public class StockIndex
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(45, MinimumLength = 3)]
public string Name { get; set; }
[StringLength(500)]
public string Description { get; set; }
public List<Component> Components { get; set; }
public StockIndex ParentStockIndex { get; set; }
public List<StockIndex> StockSubIndices { get; set; }
public StockIndex()
{
StockSubIndices = new List<StockIndex>();
}
}
它创建了一个 table 与 PK 和 FK,就像你期望的那样:
CREATE TABLE [dbo].[StockIndex] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (45) NULL,
[Description] NVARCHAR (500) NULL,
[ParentStockIndex_Id] INT NULL,
CONSTRAINT [PK_dbo.StockIndex] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.StockIndex_dbo.StockIndex_ParentStockIndex_Id] FOREIGN KEY ([ParentStockIndex_Id]) REFERENCES [dbo].[StockIndex] ([Id])
);
效果很好。我已经为它搭建了所有的 CRUD 并且一切正常。但是,这迫使我在进行编辑时在我的控制器中触发一个额外的查询,以便查找 "parent" 记录并将其分配给新记录。我想访问 table 中的 "ParentStockIndex_Id" 字段,因此我可以直接从下拉列表中分配它并跳过额外的查找查询。我尝试映射它:
public class StockIndex
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(45, MinimumLength = 3)]
public string Name { get; set; }
[StringLength(500)]
public string Description { get; set; }
public List<Component> Components { get; set; }
public int ParentStockIndex_Id { get; set; }
[ForeignKey("ParentStockIndex_Id")]
public StockIndex ParentStockIndex { get; set; }
public List<StockIndex> StockSubIndices { get; set; }
public StockIndex()
{
StockSubIndices = new List<StockIndex>();
}
}
但是当我的 DbContext 中播种数据时 运行 它出现异常:
无法确定 'MyApp.Models.StockIndex_ParentStockIndex' 关系的主体端。多个添加的实体可能具有相同的主键。
我确定我做错了什么,但如果可能的话,我想在不使用 Fluent 的情况下做到这一点。
您应该使用 public int? ParentStockIndex_Id { get; set; }
来设置不需要的 Parent(您看到 int 后面的问号了吗)。