none
One to One With Cascade RRS feed

  • Question

  • Hello,

    I am trying to setup a one to one relationship where when the main side is deleted, the detail will be cascaded.

    My entities are this:

    public class Principal
    {
    	public int PrincipalId { getset; }
    	public virtual Detail Detail { getset; }
    	public string SomeProperty { getset; }
    }
    public class Detail
    {
    	[Key]
    	[ForeignKey("Principal")]
    	public int PrincipalId { getset; }
    	[Required]
    	public Principal Principal { getset; }
    	public string AnotherProperty { getset; }
    }

    I tried several approaches, from attributes to fluent API, but nothing. What happens is this:

    var principal = ctx.Principals.Find(1);
     
    ctx.Entry(principal).State = EntityState.Deleted;
     
    ctx.SaveChanges();

    With this I get an DbEntityValidationException complaining about the Principal property of the Detail instance, which cannot be null.

    Like I said, also tried fluent API (removed all attributes from entities first):

    modelBuilder.Entity<Principal>().HasOptional(x => x.Detail).WithRequired(x => x.Principal).WillCascadeOnDelete(true);
    modelBuilder.Entity<Detail>().HasKey(x => x.PrincipalId);

    This way I get an InvalidOperationException about the relationship that could not be changed because one or more of the foreign-key properties is non-nullable.

    What is the proper way to map this?

    Thanks in advance!

    RP

    Saturday, August 31, 2013 8:10 PM

Answers

  • OK, I may have asked too early... here's how I (seem to have) fixed it:

    public class Principal
    {
    	public int PrincipalId { getset; }
    	public virtual Detail Detail { getset; }
    	public string SomeProperty { getset; }
    }
    
    

    publicclassDetail { [Key] [ForeignKey("Principal")] publicint PrincipalId { getset; } [Required] publicPrincipal Principal { getset; } publicstring AnotherProperty { getset; } }

    And:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    	modelBuilder.Entity<Principal>().HasOptional(x => x.Detail).WithRequired(x => x.Principal).WillCascadeOnDelete(true);
     
    	base.OnModelCreating(modelBuilder);
    }

    It appears to be OK. Any comments?

    RP

         

    Saturday, August 31, 2013 8:29 PM

All replies

  • OK, I may have asked too early... here's how I (seem to have) fixed it:

    public class Principal
    {
    	public int PrincipalId { getset; }
    	public virtual Detail Detail { getset; }
    	public string SomeProperty { getset; }
    }
    
    

    publicclassDetail { [Key] [ForeignKey("Principal")] publicint PrincipalId { getset; } [Required] publicPrincipal Principal { getset; } publicstring AnotherProperty { getset; } }

    And:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    	modelBuilder.Entity<Principal>().HasOptional(x => x.Detail).WithRequired(x => x.Principal).WillCascadeOnDelete(true);
     
    	base.OnModelCreating(modelBuilder);
    }

    It appears to be OK. Any comments?

    RP

         

    Saturday, August 31, 2013 8:29 PM
  • Hello,

    Thanks for sharing your solution to us, I think it will help others who have the same problem.

    Thanks a lot.

    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Tuesday, September 3, 2013 1:32 AM
    Moderator