Which way around do cascading deletes go in a one-

2020-08-13 04:26发布

问题:

Using Entity Framework code-first approach.

Suppose I have two entity classes:

[Table("Objects")]
public class DbObject : IValidatableObject
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

    public virtual ICollection<DbObjectProperty> Properties { get; set; }
}

[Table("ObjectProperties")]
public class DbObjectProperty
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }

    [Display(Name = "Object"), UIHint("Object")]
    public long ObjectId { get; set; }
    public virtual DbObject Object { get; set; }
}

Points to note here:

  • DbObject only has a navigation property, but no column with a foreign key
  • DbObjectProperty has a navigation property and a corresponding column with a foreign key
  • It should be obvious that if I delete an object, I want its properties to go with it, but if I delete a single property, I don’t want the entire object to disappear.

In the OnModelCreating method for the DB context, up until now I had the following to define the relationship:

modelBuilder.Entity<DbObjectProperty>()
    .HasRequired(op => op.Object)
    .WithMany(obj => obj.Properties)
    .HasForeignKey(op => op.ObjectId)
    .WillCascadeOnDelete(false);

Of course, this means no cascaded deletes will occur. My question is: if I change this to true, does that do what I want? Remember if I delete an object, I want its properties to go with it, but if I delete a single property, I don’t want the entire object to disappear.

The auto-generated migration code for this change (from false to true) is this:

DropForeignKey("ObjectProperties", "ObjectId", "Objects");
DropIndex("ObjectProperties", new[] { "ObjectId" });
AddForeignKey("ObjectProperties", "ObjectId", "Objects", "Id", cascadeDelete: true);
CreateIndex("ObjectProperties", "ObjectId");

I am worried that this seems to imply that deleting a property will delete its associated object. Will it?

回答1:

The direction of Cascading Delete of a relationship in the database is defined by what is the principal (table of the primary/unique key) and what is the dependent (table of the foreign key) of this relationship.

Then, if you delete the principal all dependents which have a foreign key value corresponding to the primary/unique key value of that principal are deleted as well. There is no cascading delete in the direction from dependent to principal.

In your case the principal is DbObject and the dependent is DbObjectProperty because it is the entity/table with the foreign key.

It would rarely make sense to have a cascading delete the other way around - especially in x-to-many relationships: If you delete a dependent (DbObjectProperty) and the principal (DbObject) would be deleted automatically, a foreign key constraint would be violated if there is any other dependent refering to the principal which is going to be deleted.

You don't need to worry.