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

标签 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 表没有变化。

最佳答案

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

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

它令人困惑,但如果您在 Visual Studio 中阅读对此的描述,它会阐明它的作用。

关于c# - 如何从 Fluent API 为外键设置 onUpdate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36987446/

相关文章:

c# - Monotouch Crashdump 缺少对我的代码的任何引用

c# - 实现一个 session 并从 mysql 表中检索?

c# - Silverlight Datagrid : Changing cell styles, 基于值

.net - 存储过程真的能提高 MS SQL/.NET 的性能吗?

sql-server - 将表格的两列合并到第三列中

asp.net-core - 如何避免在插入 EF Core 后选择插入的实体?

c# - LINQ 到实体 : queryable extension method not reconized inside where condition

sql - 删除大量数据后测量数据库可用空间

c# - 带有 Id 的 GET 上的 OData ASP.Net Core?

entity-framework - 在FromSql Entity Framework Core方法中使用Inner Join