I am using EF code first, and i generate my codes with EF 4.X DbContext Fluent Generator T4, so now i have have 2 poco Entities(I changed my lists to BindingList<T>
to use binding in winForms):
public partial class Parent
{
public Parent()
{
this.Childs = new BindingList<Childs>();
}
int _ParentId;
public int ParentId { get; set; }
BindingList<Child> _Childs;
public virtual BindingList<Child> Childs { get; set; }
}
public partial class Child
{
int _ChildId;
public int ChildId { get; set; }
int _ParentId;
public int ParentId { get; set; }
Parent_Parent;
public virtual Parent Parent { get; set; }
}
and also my mapping files are as:
public Parent_Mapping()
{
this.HasKey(t => t.ParentId);
this.ToTable("Parent");
this.Property(t => t.ParentId).HasColumnName("ParentId");
}
public Child_Mapping()
{
this.HasKey(t => t.ChildId);
this.ToTable("Child");
this.Property(t => t.ChildId).HasColumnName("ChildId");
this.Property(t => t.ParentId).HasColumnName("ParentId").IsRequired();
this.HasRequired(t => t.Parent)
.WithMany(t => t.Childs)
.HasForeignKey(t=>t.ParentId)
.WillCascadeOnDelete(true);
}
and in my DbContext i have these codes:
public partial class MyContext : DBContext
{
static MyContext()
{
Database.SetInitializer<MyContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Configurations.Add(new Parent_Mapping());
modelBuilder.Configurations.Add(new Child_Mapping());
}
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Childs { get; set; }
}
so i have an one-to-many relationship whit enabled cascade deleting.
but when i want to delete a parent entity, i got this error:
{
"Cannot insert the value NULL into column 'ParentId', table 'MyDB.dbo.Child';
column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."
}
when i used EF Profiler for monitoring, i saw that EF wants to update Child table to set ParentId to Null, instead delete parent entity!:
update [dbo].[Child]
set
[ParentId] = null,
where ([ChildId] = 2 /* @1 */)
where is my mistake?
IMHO the reason is that you have the child loaded together with your parent. In such case you must also delete the child. If you only delete parent EF will just set relation to null. EF will not make cascade delete. Cascade delete is only used in the database and only when you do not have the child loaded. If you have the child loaded its update is performed before deletion of the parent entity and this exception occurs.
If you want to have behavior similar to cascade delete for loaded entities as well you must use something called identifying relationship (your child entity will have primary key composed from its id and parent id).