如何从Fluent API为外键设置onUpdate?

时间:2016-05-02 16:45:16

标签: c# sql-server entity-framework-core

我试图在Entity Framework 7中获取外键关系,以便在sql约束上应用ON DELETE CASCADEON UPDATE CASCADE

OnModelCreating中使用模型构建器时,我能够指定在删除时使用级联的关系。它找到了指定我需要帮助的更新操作的位置。

以下是我的示例模型代码:

class DatabaseContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("...connection string...");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Comment>()
            .HasOne(c => c.Post)
            .WithMany(p => p.Comments)
            .HasForeignKey(c => c.PostName)
            .OnDelete(DeleteBehavior.Cascade); 
            //if you delete the post, delete its comments

        modelBuilder.Entity<Comment>().HasKey(c => new { c.Number, c.PostName });
    }
}

class Post
{
    [Required, Key, StringLength(100)]
    public string Name { get; set; }
    public string Contents { get; set; }
    public List<Comment> Comments { get; set; }
}

class Comment
{
    public int Number { get; set; }
    [Required]
    public Post Post { get; set; }
    [Required, StringLength(100)]
    public string PostName { get; set; }
    public string Contents { get; set; }
}

当我运行Add-Migration First时,这是Up方法生成的代码。

migrationBuilder.CreateTable(
    name: "Post",
    columns: table => new
    {
        Name = table.Column<string>(nullable: false),
        Contents = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Post", x => x.Name);
    });
migrationBuilder.CreateTable(
    name: "Comment",
    columns: table => new
    {
        Number = table.Column<int>(nullable: false),
        PostName = table.Column<string>(nullable: false),
        Contents = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Comment", x => new { x.Number, x.PostName });
        table.ForeignKey(
            name: "FK_Comment_Post_PostName",
            column: x => x.PostName,
            principalTable: "Post",
            principalColumn: "Name",
            onDelete: ReferentialAction.Cascade
            // ,onUpdate: ReferentialAction.Cascade
            );
    });

请注意,最后一个参数已注释掉;之后我手动添加了这个。如果我取消注释该行,则创建的sql表 已应用ON UPDATE CASCADE

现在我需要手动更改我的迁移文件以添加更新级联支持。在创建迁移文件时,我可以在Fluent API中为迁移引擎添加onUpdate: ReferentialAction.Cascade吗?

Searching through the github code给出了一些有趣的结果,也是我弄清楚手动编辑迁移文件的方法。

CSharpMigrationOperationGenerator课程中Generate方法处理AddForeignKeyOperation has a section来编写onUpdate:,因此生成器必须能够编写我需要的价值。我该如何触发它?

在尝试给出答案时,我在OnModelCreating中创建了外键后添加了以下内容:

modelBuilder.Entity<Comment>()
    .Property(p => p.PostName)
    .ValueGeneratedOnAddOrUpdate();

创建的迁移与没有此代码时创建的迁移相同,因此生成的sql表中没有任何更改。

1 个答案:

答案 0 :(得分:0)

这让我陷入了一段时间。您需要访问该属性本身才能执行此操作。

modelBuilder.Entity<Comment>()
   .Property(c => c.YourProperty)
   .ValueGeneratedOnAddOrUpdate();

令人困惑但是如果你在Visual Studio中阅读了它的描述,它将会对它的作用有所了解。