Cascade Delete Rule in EF 4.1 Code First when using Shared Primary Key Association

10,474

Solution 1

The following fluent API code perfectly switch on the cascade delete on the database:

public class Student
{   
    public virtual int StudentId { get; set; }
    public virtual Anamnesis Anamnesis { get; set; }
}

public class Anamnesis
{        
    public int AnamnesisId { get; set; }
    public virtual Student Student { get; set; }
}

public class Context : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Anamnesis> Anamnesises { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>()
                    .HasRequired(s => s.Anamnesis)
                    .WithRequiredPrincipal(a => a.Student)
                    .WillCascadeOnDelete();
    }
}

enter image description here

Solution 2

Also, you can use [Required] Attribute, and it will automatically set the delete rule to "CASCADE" mode in related relationship. (and also set "Allow Null" property of that entity to "false" in DB)

Share:
10,474
Leniel Maccaferri
Author by

Leniel Maccaferri

Started learning how to develop software in 2000 and never stopped. 10+ years of experience | dual citizenship [Brazilian-Italian] Microsoft webstack: .net, .net-core, asp.net, asp.net-core, asp.net-mvc asp.net-web-api, azure, azuread Front-end: reactjs, angular, typescript, etc... Data science: python | Business Intelligence: powerbi

Updated on June 04, 2022

Comments

  • Leniel Maccaferri
    Leniel Maccaferri almost 2 years

    I implemented a bidirectional 1:1 relationship based on this answer:

    Primary /Foreign Key in Entity Framework

    I define the bidirectional relation this way:

    public class Student
    {   
        public virtual int StudentId { get; set; }
        public virtual Anamnesis Anamnesis { get; set; }
    
        . . .
    }
    
    public class Anamnesis
    {
        [Key, ForeignKey("Student")]
        public int AnamnesisId { get; set; }
    
        public virtual Student Student { get; set; }
    
        . . .
    }
    

    where, Student is the principal entity and Anamnesis it the entity that shares the PK.

    Now I'd like that the relationship created had a Delete Rule = CASCADE. Actually, the relationship that is being created has Delete Rule = NO ACTION as seen in the following picture:

    enter image description here

    If I manually delete this relation inside the Table Properties window and add other relation with Delete Rule = CASCADE, the code works as I expect allowing me to delete a Student and it's shared Anamnesis that has the same ID.

    So, here goes my question:

    Is there a way of using Data Annotation (not Fluent API) in my class so that I get a Relation with CASCADE delete rule? I'd prefer using Data Annotation but if it's not possible, I'd be happy with some Fluent API code that makes this work.

    NOTE

    I have tried the Fluent API code that is shown in this post. It doesn't work in my case where I have bidirectional properties.

    • Leniel Maccaferri
      Leniel Maccaferri almost 13 years
      Uhmmm... now that I posted the question I see that I forgot the virtual keyword for the AnamnesisId property to comply with Ladislav's answer linked above. Maybe this is the problem. I must retest it all over again. :D
    • Ladislav Mrnka
      Ladislav Mrnka almost 13 years
      Can you show full code? EF code-first uses cascade delete by default every time it is possible and both my examples in linked question use it as well.
    • Leniel Maccaferri
      Leniel Maccaferri almost 13 years
      @Ladislav: tested it again and checked the relation created in the database. It remains the same. No CASCADE. So, the virtual keyword isn't the problem. The code that defines the relationship is the one I show above. Do you need anything more?
    • Ladislav Mrnka
      Ladislav Mrnka almost 13 years
      Can you test this against full SQL server?
    • Leniel Maccaferri
      Leniel Maccaferri almost 13 years
      @Ladislav: I'd test it, but @Morteza showed how to implement this using Fluent API code. Thanks anyway for your help.
    • angularsen
      angularsen over 11 years
      I have the exact same scenario and would very much like to find a solution that does not use Fluent API. I use code first migration and see that the foreign key is not created with cascade delete. With the Fluent API solution the migration code has cascade delete. I have tried using [Required] but it does not seem to have any effect. Using EF 5.0.
  • Leniel Maccaferri
    Leniel Maccaferri almost 13 years
    Thanks! This did the trick. By the way: you have an excellent blog. Keep up the great work you're doing here and there. God bless your life.
  • Morteza Manavi
    Morteza Manavi almost 13 years
    @Leniel: Thanks for your kind words and it is such a pleasure to hear that you found the blog posts useful :)
  • angularsen
    angularsen over 11 years
    This solution works for me, I just wish there was a Data Annotation equivalent that also works.
  • Leniel Maccaferri
    Leniel Maccaferri over 11 years
    @MortezaManavi: do you have any idea about this comment? stackoverflow.com/questions/5825799/… Just copy and paste the URL in case it does not go to the comment...