实体框架代码优先迁移忽略 [Key] 并强制复合键
Posted
技术标签:
【中文标题】实体框架代码优先迁移忽略 [Key] 并强制复合键【英文标题】:Entity Framework code-first migration ignoring [Key] and forcing composite key 【发布时间】:2022-01-12 02:28:44 【问题描述】:我正在尝试使用 [Key]
创建具有 Guid 主键的对象,但 Entity Framework 不断强制创建复合键。
public class Challenge
[Key]
public Guid Id get; set;
public Guid ChallengerId get; set;
public Guid ChallengeeId get; set;
[ForeignKey("ChallengerId")]
public virtual Player Challenger get; set;
[ForeignKey("ChallengeeId")]
public virtual Player Challengee get; set;
public DateTime Initiated get; set;
及其迁移...
migrationBuilder.CreateTable(
name: "Challenges",
columns: table => new
ChallengerId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
ChallengeeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Initiated = table.Column<DateTime>(type: "datetime2", nullable: false)
,
constraints: table =>
table.PrimaryKey("PK_Challenges", x => new x.ChallengerId, x.ChallengeeId );
table.ForeignKey(
name: "FK_Challenges_Players_ChallengeeId",
column: x => x.ChallengeeId,
principalTable: "Players",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Challenges_Players_ChallengerId",
column: x => x.ChallengerId,
principalTable: "Players",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
);
请注意,我使用相同的方法创建了 Player 类,并且 Entity Framework 尊重那里的 [Key]
属性。
public class Player
[Key]
public Guid Id get; set;
public string UserId get; set;
[ForeignKey("UserId")]
public virtual IdentityUser User get; set;
public virtual ICollection<Game> Games get; set;
[InverseProperty("Challenger")]
public virtual ICollection<Challenge> OutgoingChallenges get; set;
[InverseProperty("Challengee")]
public virtual ICollection<Challenge> IncomingChallenges get; set;
migrationBuilder.CreateTable(
name: "Players",
columns: table => new
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
UserId = table.Column<string>(type: "nvarchar(450)", nullable: false)
,
constraints: table =>
table.PrimaryKey("PK_Players", x => x.Id);
table.ForeignKey(
name: "FK_Players_IdentityUser_UserId",
column: x => x.UserId,
principalTable: "IdentityUser",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
);
即使我进入迁移和改变
table.PrimaryKey("PK_Challenges", x => new x.ChallengerId, x.ChallengeeId );
到
table.PrimaryKey("PK_Challenges", x => x.Id);
Entity Framework 似乎在苦苦挣扎,因为它使用复合键在 SQL 数据库中创建 Challenges
。
我正在使用 .NET 6。
【问题讨论】:
你有流畅的api吗? 我不确定?这是一个相当新的/稀疏的项目。为什么这会影响实体构建器? 【参考方案1】:您的 Player 模型中可能缺少 [Key] 属性吗?
public class Player
//Here should be a [Key] annotation
public Guid Id get; set;
public string UserId get; set;
[ForeignKey("UserId")]
public virtual IdentityUser User get; set;
public virtual ICollection<Game> Games get; set;
[InverseProperty("Challenger")]
public virtual ICollection<Challenge> OutgoingChallenges get; set;
[InverseProperty("Challengee")]
public virtual ICollection<Challenge> IncomingChallenges get; set;
【讨论】:
看起来我是,尽管我的播放器模型的行为符合预期。这可能会阻止外键正确映射。让我看看,然后回复你。谢谢你的收获! 不是这样的。我会更新问题 - 玩家 ID 有[Key]
。此外,IIRC,它不应该需要它 - Id 约定应该默认为主键,对吧?
嗯,我认为你是对的。但是,通过自动迁移,两个版本都成功地创建了我的表和约束。【参考方案2】:
我找到了罪魁祸首:AppDbContext.cs
modelBuilder.Entity<Challenge>()
.HasForeignKey(c => new c.ChallengerId, c.ChallengeeId );
【讨论】:
以上是关于实体框架代码优先迁移忽略 [Key] 并强制复合键的主要内容,如果未能解决你的问题,请参考以下文章