First of all, apologies if I\'m missing some basic stuff here but I\'m new to EF and still getting my head around setting up the DB code first....
I\'m having a
You need to disable cascade deletes for all but one of the possible paths. In your case you have the following paths:
Project -> UseCase
Project -> Actor -> UseCase
You can allow a single path for cascading deletion of UseCase
- via the Project
entity or Actor
entity. However, if we disable cascading deletes in the Project
-> UseCase
path, we'll still achieve a cascading delete via Actor
:
modelBuilder.Entity<Project>()
.HasMany( p => p.UseCases )
.WithRequired( uc => uc.Project )
.HasForeignKey( uc => uc.ProjectID )
.WillCascadeOnDelete( false ); // disable this cascading delete
modelBuilder.Entity<Project>()
.HasMany( p => p.Actors )
.WithRequired( a => a.Project )
.HasForeignKey( a => a.ProjectID )
.WillCascadeOnDelete( true ); // this works
modelBuilder.Entity<Actor>()
.HasMany( a => a.UseCases )
.WithRequired( uc => uc.Actor )
.HasForeignKey( uc => uc.ActorID )
.WillCascadeOnDelete( true ); // and this works
Side note:
Your model has a data inconsistency hazard - both Actor
and UseCase
have a FK to Project
via ProjectID
, but there is nothing in the model to enforce the Actor
referenced by a UseCase
has the same ProjectID
- an Actor
from "Project 1" could be reference by a UseCase
from "Project 2". You could include the ProjectID
in the Actor
PK and then in the UseCase
->Actor
FK, ensuring that the Actor
referenced by a UseCase
belongs to the same Project
, but this would technically violate the 2NF.
The 'proper' model is probably a Project
->Actors
->UseCases
hierarchy, simply requiring you to join through Actors
to get a Project
's UseCase
s
You need to make ActorID
in your UseCase
class as a nullable int. EF is throwing that error because it sees 2 foreign keys that are required in a single class. Having that would create multiple cascade paths--something that SQL Server is, unfortunately, ill-equipped to handle.
In any case, making Actor
optional on your UseCase
class will mean that the Actor
won't be deleted when the UseCase
is, which I believe is your intent.