EF Core复合键,一个外置,一个自动递增
本文关键字:一个 EF 复合 Core | 更新日期: 2023-09-27 18:02:26
我有这个实体:
public class PlayerScoreHistory
{
public int Id { get; set; }
public int PlayerScoreId { get; set; }
public DateTime ScoreWhen { get; set; }
}
我需要从这两个Id
字段中生成一个复合键。PlayerScoreId
需要是PlayerScore.Id
的外键。Id
需要是一个自动递增的id。
所以,我得到了:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<PlayerScoreHistory>()
.HasKey(x => new { x.Id, x.PlayerScoreId });
}
这给了我组合键。我做了Add-Migration Initial
来给我初始的迁移。
constraints
参数中添加一行:
migrationBuilder.CreateTable(
name: "PlayerScoreHistories",
columns: table => new
{
Id = table.Column<int>(nullable: false),
PlayerScoreId = table.Column<int>(nullable: false),
ScoreWhen = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PlayerScoreHistories", x => new { x.Id, x.PlayerScoreId });
table.ForeignKey("FK_PlayerScoreId", arg => new { arg.PlayerScoreId}, "PlayerScores", "Id");
});
两个问题:
- 如何在
OnModelCreating
方法中获得外键创建? - 我如何使
Id
列数据库生成字段,并确保EF核心不尝试设置值?
我不确定有什么选择对我开放,因为EF Core是非常新的…
我得到的两个错误:
1。
当我将这行添加到Id
column
参数配置中时:
Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
我当IDENTITY_INSERT设置为OFF时,SQL无法在表' table '中插入标识列的显式值[duplicate]
2。
当我删除一行然后尝试添加一个实体时,我得到:
Id
列不能插入null
显然我在某处....
编辑至今
我决定删除Id
列,只使用PlayerScoreId
和ScoreWhen
作为复合键....
但是,我仍然有一个问题是如何使OnModelCreating
身份PlayerScoreId
作为外键-没有导航属性.....
但是,我仍然有一个问题是如何使OnModelCreating身份PlayerScoreId作为一个外键-没有导航属性.....
您可以使用HasOne
/WithMany
(或HasMany
/WithOne
)方法而不指定导航属性,像往常一样与HasForeignKey
结合使用:
modelBuilder.Entity<PlayerScoreHistory>()
.HasOne<PlayerScore>()
.WithMany()
.HasForeignKey(e => e.PlayerScoreId);
首先,编辑迁移文件为您提供所需的数据库,但是EF运行时将不知道这些更改。运行时需要的所有信息应该只在模型中配置。
因此得到exception
当IDENTITY_INSERT设置为OFF时,SQL无法在表' table '中插入标识列的显式值[duplicate]
因为EF运行时不知道标识列,所以它将发送0 (default(int)
)作为插入语句中标识列的值。
我不能得到第二个异常,因为EF不会(&不能)尝试为int
类型属性插入空,因为值在c#世界中不能为空。
现在回答你的问题:
-
Ivan的答案是正确的。这就是在modelbuilder中配置外键的方法。
modelBuilder.Entity<PlayerScoreHistory>() .HasOne<PlayerScore>() .WithMany() .HasForeignKey(e => e.PlayerScoreId);
有关如何配置关系的更多信息- https://ef.readthedocs.io/en/latest/modeling/relationships.html
-
要告诉
Id
是数据库生成的字段,在modelbuilder中使用以下代码:modelBuilder .Entity<PlayerScoreHistory>() .Property(e => e.Id) .ValueGeneratedOnAdd();
这将告诉EF在插入实体时生成Id
的值,如果为ValueGeneratedOnAdd
配置了1个整数列,则在SqlServer上将其转换为Identity
。有关生成属性的更多信息,请访问https://ef.readthedocs.io/en/latest/modeling/generated-properties.html#value-generated-on-add