Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a cascade delete rule be added in a migration?

In a FluentMigrator migration, if I'm defining a relationship, say:

Create.Table("RelatedTable")
    .WithColumn("RelatedTableId").AsGuid().PrimaryKey()
    .WithColumn("MainTableId").AsGuid().NotNullable();
    .WithColumn("SomeInfo").AsString().NotNullable();

Create.Table("MainTable")
    .WithColumn("MainTableId").AsGuid().PrimaryKey()
        .ReferencedBy("FK_RelatedTable_RelatedTableId", "RelatedTable", "MainTableId")
    .WithColumn("AField").AsInt64().NotNullable()
    .WithColumn("AnotherField").AsString().NotNullable();

Is there any way to define cascading delete type of relationship between them? Eg, if you delete something from MainTable, any related records are also deleted?

like image 590
Remi Despres-Smyth Avatar asked Oct 17 '11 00:10

Remi Despres-Smyth


People also ask

When to use cascading delete?

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

How do you add cascade delete to existing FK constraint in Postgres?

If you want to add an on delete cascade to an existing foreign key constraint, you are going to need two statements. The first statement will drop the constraint and the second statement will recreate it with the addition of the on delete clause.


2 Answers

You can create a separate foreign key in the same migration like this, with the option of setting your cascading rules:

Create.ForeignKey("FK_RelatedTable_RelatedTableId")
               .FromTable("RelatedTable").ForeignColumn("RelatedTableId")
               .ToTable("MainTable").PrimaryColumn("MainTableId")
               .OnDeleteOrUpdate(System.Data.Rule.Cascade);

Hope this helps.

like image 85
Gitte Avatar answered Oct 05 '22 10:10

Gitte


The best I've been able to do on short notice is to execute the SQL to create the relationship myself. I created an extension method that does this and adds a cascade delete, as this is the only option I need for this project:

public static void AddCascadeDeleteRelationship(
    this Migration db,
    String primaryTable,
    String primaryField,
    String foreignTable,
    String foreignField,
    String relationshipName)
{
    db.Execute.Sql(
        String.Format(
            "ALTER TABLE [{0}] ADD CONSTRAINT {1} FOREIGN KEY ( [{2}] ) " +
                "REFERENCES [{3}] ( [{4}] ) ON DELETE CASCADE;",
            foreignTable, relationshipName, foreignField, primaryTable, primaryField)
    );
}

Is there a better way?

like image 38
Remi Despres-Smyth Avatar answered Oct 05 '22 11:10

Remi Despres-Smyth