entity-framework - 在 EF Core 中添加外键列

标签 entity-framework entity-framework-migrations ef-core-2.0

我有一个现有的表 Projects我想添加一个 UserId列到,哪里UserId是外键。 Projects现在有一个名字列表,但我希望每个用户都管理自己的项目。我最初可以接受“孤儿”,因为列表足够小,我可以手动清理它们。

我已更新我的模型以包含 UserId和导航属性 User (可能不相关,但 Entity 这里是带有 IdDateModified 的基类)

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 来删除迁移。然后再次运行添加迁移。这次你应该有这个:
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 类。

关于entity-framework - 在 EF Core 中添加外键列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47824667/

相关文章:

entity-framework - 如何使用 Entity Framework 4 继承来确定实体的子类型?

vb.net - 如何覆盖默认的 SQL 迁移生成器?

c# - 使用 EF Core 和 ExecuteSqlCommandAsync 从存储过程中的 SELECT 语句访问结果

c# - EF Core DbUpdateConcurrencyException 未按预期工作

LINQ to Entities 三表连接查询

asp.net-mvc - 为什么我针对 Azure SQL 使用 OWIN 身份验证时收到 "The magic number in GZip header is not correct."错误

asp.net - ADO.NET Entity Framework 或 ADO.NET

entity-framework-core - 无法创建 CoreCLR,HRESULT : 0x80004005 when trying to run Entity Framework CLI

entity-framework - 如何在 EF Core 中配置固定长度的列?

c# - TDD:EF Core In Memory Provider 是否验证引用约束?