如何编写匹配SQL表设计的Entity Framework Core模型类
问题
需要编写匹配以下SQL Server表设计的EF Core模型类,确保生成的迁移代码能完全重建原表(不能修改列名或新增列):
CREATE TABLE ParentTable ( ParentID INT PRIMARY KEY, UniColumn INT UNIQUE ); CREATE TABLE ChildTable ( ChildID INT PRIMARY KEY, FOREIGN KEY (ChildID) REFERENCES ParentTable(UniColumn) );
当前编写的模型类如下:
[Index(nameof(UniColumn), IsUnique = true)] public class ParentTable { [Key] public int ParentID { get; set; } [Required] public int UniColumn { get; set; } public ICollection<ChildTable> ChildTables { get; set; } } public class ChildTable { [Key] public int ChildID { get; set; } [ForeignKey("ParentTable")] public int UniColumn { get; set; } public ParentTable ParentTable { get; set; } }
生成的迁移代码存在两个问题:
- 外键约束错误关联了
ParentID而非UniColumn ChildTable中多生成了UniColumn列
迁移代码片段:
migrationBuilder.CreateTable( name: "ParentTables", columns: table => new { ParentID = table.Column<int>(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), UniColumn = table.Column<int>(type: "int", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ParentTables", x => x.ParentID); }); migrationBuilder.CreateTable( name: "ChildTables", columns: table => new { ChildID = table.Column<int>(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), UniColumn = table.Column<int>(type: "int", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ChildTables", x => x.ChildID); table.ForeignKey( name: "FK_ChildTables_ParentTables_UniColumn", column: x => x.UniColumn, principalTable: "ParentTables", principalColumn: "ParentID", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( name: "IX_ChildTables_UniColumn", table: "ChildTables", column: "UniColumn"); migrationBuilder.CreateIndex( name: "IX_ParentTables_UniColumn", table: "ParentTables", column: "UniColumn", unique: true);
解决方案
需要调整模型类配置,明确外键关联逻辑并移除多余列,具体修改如下:
1. 核心调整点
- 移除
ChildTable的UniColumn属性:原表中ChildID既是主键又是外键,不需要额外列 - 明确外键关联关系:通过
[ForeignKey]特性指定ChildTable的ChildID作为外键,关联ParentTable的UniColumn列 - 关闭主键自动增长:原SQL未设置
IDENTITY,需移除EF Core默认的自动增长配置
2. 修改后的完整模型类
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; [Index(nameof(UniColumn), IsUnique = true)] public class ParentTable { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] // 匹配原SQL,关闭自动增长 public int ParentID { get; set; } [Required] public int UniColumn { get; set; } public ICollection<ChildTable> ChildTables { get; set; } } public class ChildTable { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] // 匹配原SQL,关闭自动增长 public int ChildID { get; set; } // 指定外键为当前实体的ChildID,关联主表的UniColumn列 [ForeignKey(nameof(ChildID), nameof(ParentTable.UniColumn))] public ParentTable ParentTable { get; set; } }
3. 验证迁移结果
调整后生成的迁移代码会完全匹配原SQL表结构:
ParentTable保留ParentID主键和UniColumn唯一约束ChildTable的ChildID同时作为主键和关联ParentTable.UniColumn的外键,无多余列- 移除了默认的
IDENTITY配置,与原SQL一致
内容的提问来源于stack exchange,提问作者user9163823
相关产品推荐
相关产品推荐

