无法删除具有子实体的实体

时间:2014-09-19 13:56:05

标签: vb.net entity-framework breeze

删除具有关联记录的记录时遇到问题。

这是一个非常简单的设置:A"组件"可以有一个或多个(或没有!)" componentProcesses"。如果删除没有进程的组件,则没有错误,并且已成功从数据库中删除该组件。如果我删除一个WITH进程的组件,那么我在调用manager.saveChanges()时得到以下消息:

The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_dbo.componentProcesses_dbo.components_ComponentID". The conflict occurred in database "mydb", table "dbo.components", column 'Id'

该模型基本上是:

Public Class component
    Public Property Id() As Integer

    ...irrelevant fields removed....

    Public Overridable Property Processes() As ICollection(Of componentProcess)        
End Class

Public Class componentProcess
    Public Property Id() As Integer

    ...irrelevant fields removed....

    Public Property ComponentID() As Integer 'process belongs to component
    Public Property ProcessId() As Integer 'links to specific process

    Public Overridable Property Component() As component
    Public Overridable Property Process() As process
End Class

我不会展示"组件"和"过程"模型,因为它们只是简单的基于身份的静态表。

当用户删除组件时,代码为:

    //editComponent is a ko.observable containing currently-being-edited component

    //editComponent().processes().forEach(function (p) {
    //    p.entityAspect.setDeleted(); //sets to deleted but won't persist if save isn't called
        //editComponent().processes.remove(function (_process) {
        //    return _process.id() == p.id()
        //});
    //});

    editComponent().entityAspect.setDeleted(); //sets to deleted but won't persist if save isn't called
    editComponent(null); //empty observable to trigger screen UI updates

从上面的代码中可以看出,我一直在尝试评论各种线条以确定它是否会影响结果,但它并没有。无论我是否设置每个孩子" componentProcess" entityaspect to"删除"不是,我在保存更改时遇到同样的错误。

Cascadedelete用于此关系,如果我删除SQL企业管理器中的组件,则会立即删除所有子组件进程,以便正常工作。

1 个答案:

答案 0 :(得分:1)

SQL错误似乎与你声称db关系设置为级联删除的说法不一致...虽然我无法解释你如何在SQL Server Management Studio中使用它。

也许您可以跟踪数据库调用的顺序?

我确实知道你删除子进程的尝试有什么问题:当你迭代它时,你正在更改editComponent.processes数组!这是禁忌。

每次调用setDeleted时,Breeze都会从父Process数组中删除editComponent.processes实体。当迭代器循环回来时,它会跳过下一个process

在对其内容调用setDeleted之前,您需要制作数组的副本。这样的事情应该这样做:

// copy with slice()
var processes = editComponent().processes().slice(); 
// iterate over the copy
processes.forEach(function (p) {
    // Breeze removes each `p` from its parent editComponent.processes array
    p.entityAspect.setDeleted(); //marks deleted but won't persist until saveChanges is called
});

expect(editComponent().processes().length).to.equal(0);

HTH