Entity framework 实体框架级联删除

Entity framework 实体框架级联删除,entity-framework,Entity Framework,首先,如果我在这里遗漏了一些基本的东西,我表示歉意,但我是EF的新手,仍然需要先设置DB代码 我有一个类似的问题,但似乎无法从那里的意见,我需要做什么与我的特定模型。当我尝试在将公共虚拟参与者{get;set;}添加到我的用例类后更新数据库时,我得到以下错误: Introducing FOREIGN KEY constraint 'FK_dbo.UseCase_dbo.Actor_ActorID' on table 'UseCase' may cause cycles or multiple c

首先,如果我在这里遗漏了一些基本的东西,我表示歉意,但我是EF的新手,仍然需要先设置DB代码

我有一个类似的问题,但似乎无法从那里的意见,我需要做什么与我的特定模型。当我尝试在将
公共虚拟参与者{get;set;}
添加到我的用例类后更新数据库时,我得到以下错误:

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.
我知道这一定与设置FK约束的方式有关(可能与删除用例有关,这意味着最终将从多个其他表中删除数据)

我尝试关闭级联删除,但仍然出现错误:

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>();
        }
更新了因此,下面是我根据以下反馈修改的代码。当我运行应用程序并尝试创建数据库时,或者当我尝试通过package manager更新数据库时,我仍然会收到相同的错误。快把我逼疯了

对我来说,下面的代码说,如果我删除一个参与者,那么也删除该参与者的用例。如果我删除一个项目,则删除该项目的参与者,因此也删除每个参与者的用例。但是如果我删除了一个项目,就不要删除用例。很明显,我误解了一件很严重的事情:——

modelBuilder.Entity()
.HasMany(a=>a.useCases)
.WithRequired(uc=>uc.actor)
.HasForeignKey(uc=>uc.ActorID)
.WillCascadeOnDelete(true);//这是有效的
modelBuilder.Entity()
.HasMany(p=>p.actors)
.WithRequired(a=>a.project)
.HasForeignKey(a=>a.projectd)
.WillCascadeOnDelete(true);//这很有效
modelBuilder.Entity()
.HasMany(p=>p.UseCases)
.WithRequired(uc=>uc.project)
.HasForeignKey(uc=>uc.ProjectID)
.WillCascadeOnDelete(false);//禁用此级联删除

您需要将
UseCase
类中的
ActorID
设置为可为null的int。EF抛出该错误是因为它在一个类中看到了两个需要的外键。这样会创建多个级联路径——不幸的是,SQL Server无法处理这一问题


在任何情况下,在
UseCase
类上设置
Actor
为可选将意味着
Actor
不会在
UseCase
为时被删除,我相信这是您的意图。

您需要禁用所有可能路径的级联删除,但其中一个路径除外。在您的情况下,您有以下路径:

Project -> UseCase
Project -> Actor -> UseCase
您可以通过
项目
实体或
参与者
实体允许单个路径级联删除
用例
。但是,如果我们在
项目
->
用例
路径中禁用级联删除,我们仍然可以通过
参与者
实现级联删除:

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
modelBuilder.Entity()
.HasMany(p=>p.UseCases)
.WithRequired(uc=>uc.Project)
.HasForeignKey(uc=>uc.ProjectID)
.WillCascadeOnDelete(false);//禁用此级联删除
modelBuilder.Entity()
.HasMany(p=>p.Actors)
.WithRequired(a=>a.项目)
.HasForeignKey(a=>a.projectd)
.WillCascadeOnDelete(true);//这很有效
modelBuilder.Entity


“适当的”模型可能是一个
项目
->
参与者
->
用例
层次结构,仅仅要求您通过
参与者
加入以获得
项目
用例

是否使用迁移?我最初忽略了这个评论(结果浪费了几个小时!)-问题确实是由迁移造成的(部分原因是迁移).由于我缺乏EF方面的经验,我正在按照下面的建议对我的模型进行更改,但没有更新数据库-我错误地认为这是自动的。我现在显然意识到自动迁移需要显式打开。我还掌握了手动操作的诀窍:-)在应用下面的更改并更新数据库之后,现在一切都正常了。万岁,没有评论!因为当人们不知道自己说错了什么的时候,他们真的可以学得很好!该模型可以配置为正确的级联删除,而无需删除对
ActorId
@IronMan84的要求。我尝试将我的用例模型更改为:
public virtual int?ActorID{get;set;}
但我仍然遇到同样的问题。要尝试上面@Moho建议的更改,我的数据库的结构显然存在问题,这里确实存在问题…更新了上面的原始问题。仍然需要一些帮助,因为尽管发生了更改,仍然会出现相同的错误。我知道我明显遗漏了什么,但我不知道你的问题是什么,那么;我的解决方案在测试时有效。我建议不要在
UseCase
中引用
Project
,只需使用
Project.Actors。如果您想获得与
项目相关的所有
UseCase
(您需要将
Actors
集合导航属性添加到
项目
)感谢Moho,我现在不在我的机器上,但今晚我会有另一把小提琴来标记这个作为答案-最初这不起作用,因为我没有通过添加迁移来更新数据库,所以无论我做了什么更改,我仍然会收到错误消息。一旦我最终意识到这一点,上面的更改就起作用了,现在级联删除没有问题了。谢谢@moho
Project -> UseCase
Project -> Actor -> UseCase
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