Here is my situation :
public abstract class Article
{
[key]
public Guid Guid { get; set;}
public string Name { get; set;}
.
.
.
}
public class Download : Article
{
...
}
public abstract class Category : Article
{
...
}
public class DownloadCategory : Category
{
....
}
And then I should have a many-to-many relation between Download and DownloadCategory
like this :
public class DownloadInCategory
{
[Key, Column(Order = 1), Required]
[ForeignKey("Download")]
Public Guid DownloadGuid { get; set; }
Public Download Download { get; set; }
[Key, Column(Order = 2), Required]
[ForeignKey("Category")]
Public Guid CategoryGuid { get; set; }
Public DownloadCategory Category { get; set; }
}
When I call Add-Migration
the created migration for DownloadInCategory
entity is :
CreateTable("dbo.DownloadInCategories",
c => new
{
CategoryGuid = c.Guid(nullable: false),
DownloadGuid = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid })
.ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid)
.ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true)
.Index(t => t.CategoryGuid)
.Index(t => t.DownloadGuid);
Here is My Question :
As you notice it's not adding cascadeDelete: true
to one of foreign keys. WHY!!!!!!?????
I should mention that I didn't change any of modelbuilder
Conventions.
So this schema should add Casscade on delete in migration. My properties are [Required]
.
What am I doing wrong?
Thanks guys...
Update :
Please notice that Article
and Category
classes are abstract
.
I changed classes above
Update 2: There is no Logical issue with this schema. If I edit the migration manually, It will update the database normally.
Update 3:
My EF Inheritance Methodology is TPC
Update 4:
After Some investigation and tests It seems problem is inheritanced from Category
.
When DownloadCategory
is Inherited from Category
, Cascade is not deployed. but when I Inherit DownloadCategory
directly from Article, Cascade is deployed.
But Why again?
I would think this is because:
DownloadCategory : Category : Article
vs
Download : Article
The key is on the Article class. Multiple DownloadCategories
could use the same Category
, so it will not cascade on delete as this could leave other DownloadCategory
's corrupted.
This is possibly a failing of Entity Framework, since you are using TPC, this should be inferred. Take a look at this article for workarounds.
Specifically these sections:
In most cases the Entity Framework can infer which type is the dependent and which is the principal in a relationship. However, when both ends of the relationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. When both ends of the relationship are required, use
WithRequiredPrincipal
orWithRequiredDependent
after theHasRequired
method. When both ends of the relationship are optional, useWithOptionalPrincipal
orWithOptionalDependent
after theHasOptional
method.
// Configure the primary key for the OfficeAssignment
modelBuilder.Entity<OfficeAssignment>()
.HasKey(t => t.InstructorID);
modelBuilder.Entity<Instructor>()
.HasRequired(t => t.OfficeAssignment)
.WithRequiredPrincipal(t => t.Instructor);
You can configure cascade delete on a relationship by using the
WillCascadeOnDelete
method. If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set tonull
.You can remove these cascade delete conventions by using:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
The following code configures the relationship to be required and then disables cascade delete.
modelBuilder.Entity<Course>()
.HasRequired(t => t.Department)
.WithMany(t => t.Courses)
.HasForeignKey(d => d.DepartmentID)
.WillCascadeOnDelete(false);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With