[英]Add Foreign Key Column In EF Core
我有一个现有的表Projects
,我想向其中添加UserId
列,其中UserId
是外键。 现在的Projects
有一个名称列表,但是我希望每个用户都可以管理自己的项目。 我最初拥有“孤儿”是可以的,因为列表足够小,我可以手动清理它们。
我已经更新了模型,以包含UserId
和导航属性User
(可能不相关,但是此处的Entity
是具有Id
和DateModified
基类)
public class Project : Entity
{
public string Name { get; set; }
public Guid? UserId { get; set; } //tried this as nullable and non nullable
public User User { get; set; }
}
我相关的映射文件是
public class ProjectMap : IEntityTypeConfiguration<Project>
{
public void Configure(EntityTypeBuilder<Project> builder)
{
builder.Property(x => x.Name).IsRequired();
builder.Property(x => x.UserId).IsRequired();
builder.HasOne(x => x.User)
.WithMany(x => x.Projects)
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.SetNull); //I have tried numerous combinations of things here....
}
}
我还向项目的User
实体添加了导航属性,但未对映射类进行任何更改。
public class User : Entity
{
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Task> Tasks { get; set; }
public List<Project> Projects { get; set; }
}
由此产生的迁移:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "UserId",
table: "Projects",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.CreateIndex(
name: "IX_Projects_UserId",
table: "Projects",
column: "UserId");
migrationBuilder.AddForeignKey(
name: "FK_Projects_Users_UserId",
table: "Projects",
column: "UserId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
运行更新数据库时会转换为此SQL
ALTER TABLE [Projects] ADD CONSTRAINT [FK_Projects_Users_UserId] FOREIGN KEY ([UserId]) REFERENCES [Users] ([Id]) ON DELETE SET NULL;
并因该错误而失败
Cannot create the foreign key "FK_Projects_Users_UserId" with the SET NULL referential action, because one or more referencing columns are not nullable.
我究竟做错了什么?
下面的行导致了此问题,因为您希望Project
FK为空
builder.Property(x => x.UserId).IsRequired();
另外,您生成的迁移已经具有提示:
nullable: false,
只需在您的Configure
方法上删除该行,它就可以工作。 您可能还需要通过运行Remove-Migration
,然后再次运行add-migration来删除迁移。 这次您应该具有以下功能:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Projects",
nullable: false,
oldClrType: typeof(string),
oldNullable: true);
migrationBuilder.AddColumn<Guid>(
name: "UserId",
table: "Projects",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Projects_UserId",
table: "Projects",
column: "UserId");
migrationBuilder.AddForeignKey(
name: "FK_Projects_Users_UserId",
table: "Projects",
column: "UserId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
如果需要,可以通过在配置关系时显式设置IsRequired
来更具体:
private static void ConfigureProject(EntityTypeBuilder<Project> b)
{
b.Property(x => x.Name).IsRequired();
b.HasOne(x => x.User)
.WithMany(x => x.Projects)
.HasForeignKey(x => x.UserId)
.IsRequired(false)
.OnDelete(DeleteBehavior.SetNull);
}
即使该属性已经可以为空,并且EF会使用其约定正确地创建它,我还是喜欢它,对于某些无需阅读实际Project类就可以阅读配置并了解它的人来说,它仍然很不错。
在功能配置中,您可以指定:
builder.Property(x => x.UserId).IsRequired();
这不是说UserId不能为null吗? 但是您希望它为空吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.