简体   繁体   中英

How do I set onUpdate for a foreign key from the Fluent API?

I'm trying to get a foreign key relationship in Entity Framework 7 to apply both ON DELETE CASCADE and ON UPDATE CASCADE on the sql constraint.

When using the model builder in OnModelCreating I'm able to specify the relationship to use cascade on deletion. It's finding out where to specify the update action that I need help.

Here is my sample model code:

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; }
}

When I run Add-Migration First , this is the generated code for the Up method.

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
            );
    });

Note that the last parameter is commented out; I added this manually afterwards. If I uncomment the line, the created sql table does have ON UPDATE CASCADE applied.

Right now I need to manually alter my migration files to add update cascade support. Is there a way within the Fluent API that I can have the migration engine add onUpdate: ReferentialAction.Cascade for me when the migration file is created?

Searching through the github code gives some interesting results, and is also how I figured out that manually editing the migration file would work.

In the CSharpMigrationOperationGenerator class, the Generate method that deals with AddForeignKeyOperation has a section for writing onUpdate: , so the generator must have the ability to write the value I need. How do I trigger it?


In attempt to an answer given, I added the following after the creation of the foreign key in OnModelCreating :

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

The migration created was identical to the migration created without this code, and thus no change in the resulting sql table.

This had me stuck for a while too. You need to access the property itself in order to do this.

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

It's confusing but if you read the description of this in Visual Studio it will shed some light on what it does.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM