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 similar problem to this Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths but can't seem to work out from the comments there what I need to do with my particular model. When I attempt to update database after adding in public virtual Actor actor { get; set; }
to my UseCase class, I get this error:
Introducing FOREIGN KEY constraint 'FK_dbo.UseCase_dbo.Actor_ActorID' on table 'UseCase' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
I know it must be something to do with the way that my FK constraints are set up (probably something to do with deleting a use case meaning that I'll end up deleting data from multiple other tables).
I tried turning off cascading delete, but still get the error:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//prevent table names created by entity framework being pluralised
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//Turn off delete cascades between parent child tables. May need to put this back in future, but for the time being it is stopping the database being updated through the package manager console (error is that a foregin key constraint may cause cycles or multiple cascade paths)
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}
Here are my models. What should happen is that only if a project is deleted should it's use cases or actors be deleted. Actors should not be deleted when a UseCase is, because they may be involved in other UseCases. Can anyone point to what I need to change?
Finally, the correct model indeed is this Project > Actors > Use Cases
. I assume that I should just remove public virtual int ProjectID { get; set; }
and public virtual Project project { get; set; }
from UseCase?
Learning hurts!
public class Project
{
public virtual int ID {get; set;}
[DisplayName ("Project Name")]
public virtual string ProjectName { get; set; }
[DisplayName("Client")]
public virtual string ClientID { get; set; }
public virtual string Description { get; set; }
[DisplayName("Use Cases")]
public virtual ICollection <UseCase> UseCases { get; set; }
}
public class UseCase
{
public virtual int ID { get; set; }
[Required]
public virtual int ProjectID { get; set; }
public virtual int ActorID { get; set; }
[Required]
public virtual Actor actor { get; set; }
public virtual string Title { get; set; }
public virtual Level? Level { get; set; }
public virtual string Precondition { get; set; }
public virtual string MinimalGuarantee { get; set; }
public virtual string SuccessGuarantee { get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Extension> Extensions { get; set; }
public virtual ICollection<Query> Queries { get; set; }
}
public class Actor
{
public virtual int ID { get; set; }
public virtual int projectID { get; set; }
public virtual Project project { get; set; }
public virtual string Title { get; set; }
[DataType(DataType.MultilineText)]
public virtual string Description { get; set; }
}
UPDATED So, here is my modified code based on feedback below. I'm still getting the same error, either when I run the application and it tries to create the DB or when I try to update the database through package manager Update-Database
. Driving me crazy.
To me, the code below says if I delete an actor, delete the use cases for that actor too. If I delete a project, delete the actors for the project and therefore delete the use cases for each actor too. But if I delete a project, don't delete the use cases. Clearly, I'm misunderstanding something quite badly :-(
modelBuilder.Entity<Actor>()
.HasMany(a => a.useCases)
.WithRequired(uc => uc.actor)
.HasForeignKey(uc => uc.ActorID)
.WillCascadeOnDelete(true); // and this works
modelBuilder.Entity<Project>()
.HasMany(p => p.actors)
.WithRequired(a => a.project)
.HasForeignKey(a => a.projectID)
.WillCascadeOnDelete(true); // this works
modelBuilder.Entity<Project>()
.HasMany(p => p.UseCases)
.WithRequired(uc => uc.project)
.HasForeignKey(uc => uc.ProjectID)
.WillCascadeOnDelete(false); // disable this cascading delete