3

我使用 Entity Framework Code First + Durandal + Breeze 进行项目。

我有这些实体模型:

public class Packing
{
    [Key]
    public int Id { get; set; }
    public string PackingDescription { get; set; }
    ...
    public virtual List<Isotope> Isotopes { get; set; }
    public virtual List<PhysicalForm> PhysicalForms { get; set; }
    public virtual List<ChemicalForm> ChemicalForms { get; set; }
}

public class Isotope
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    ...
    public int PackingId { get; set; }
    public virtual Packing Packing { get; set; }
}

public class ChemicalForm
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    ...
    public int PackingId { get; set; }
    public virtual Packing Packing { get; set; }
}

public class PhysicalForm
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    ...
    public int PackingId { get; set; }
    public virtual Packing Packing { get; set; }
}

当我运行我的项目时,我的 Entity Framework Code First 数据库被创建。

首先,我直接在我的数据库中“手动”测试级联删除。当我有一个包含多个同位素的 Packing 并删除 Packing 时,所有级联的同位素都将被删除。这对我来说没问题。

现在在我的项目运行时使用微风,当我尝试相同的场景时:删除这样的Packing元素:

var deletePackings = function (packingsObservable) {

    // Input: packingsObservable: an observable filled with a list of packings to delete
    // Output: none

    for (var i = 0; i < packingsObservable().length; i++) {
        packingsObservable()[i].entityAspect.setDeleted();
    };
    return manager.saveChanges();
};

我收到以下错误:

UPDATE 语句与 FOREIGN KEY 约束 \"FK_dbo.Isotopes_dbo.Packings_PackingId\" 冲突。数据库 \"TRANSPORTBOEKDB\"、表 \"dbo.Packings\"、列 'Id' 中发生冲突。\r\n语句已终止。"}

现在我在另一个SO 帖子上读到

Breeze 尚不支持客户端“级联”删除(我们正在考虑这一点),您将需要遍历任何已加载的客户端订单并“分离”它们。

那么这就是我在应用程序中出现错误的原因吗?

我是否必须遍历已加载的任何子实体并“分离”它们?


更新

通过使用代码手动分离任何子实体来解决问题,但这很痛苦:

var deletePackings = function (packingsObservable) {

    // Input: packingsObservable: an observable filled with a list of packings to delete
    // Output: none
    // Remark: we loop from end to begin of the observable!

    var entity;

    // Since Breeze does not yet support client side 'cascaded' deletes (we are considering this one), 
    // you will need to iterate over any child entity that are already loaded and 'detach' them.

    for (var i = packingsObservable().length - 1; i >= 0; i--) {

        // Detach any child entities of type isotope
        for (var j = packingsObservable()[i].isotopes().length - 1; j >= 0; j--) {
            entity = packingsObservable()[i].isotopes()[j];
            manager.detachEntity(entity);
        }

        // Detach any child entities of type chemicalForm
        for (var j = packingsObservable()[i].chemicalForms().length - 1; j >= 0; j--) {
            entity = packingsObservable()[i].chemicalForms()[j];
            manager.detachEntity(entity);
        }

        // Detach any child entities of type physicalForm
        for (var j = packingsObservable()[i].physicalForms().length - 1; j >= 0; j--) {
            entity = packingsObservable()[i].physicalForms()[j];
            manager.detachEntity(entity);
        }

        packingsObservable()[i].entityAspect.setDeleted();
    };


    return manager.saveChanges();
};

没有更好的解决方案?

4

3 回答 3

2

如果需要,在 SQL 中进行级联删除并在客户端忘记,然后刷新数据。

或者您可以为 agreggate 实体添加新的 IsActive 列,这是我的首选方法,我害怕删除数据库:)

于 2013-04-25T18:46:16.410 回答
1

微风作者正在考虑的功能是客户端级联删除,但微风也不支持服务器端级联删除。您必须执行某些操作才能使用服务器端级联删除。

setDeleted 将缓存中所有引用的 fkey 值归零——即使 fkey 不可为空。如果引用记录具有不可为空的 fkey 约束,则需要防止保存子记录,因为 UPDATE 会失败。您可以在 save 完成此目标之前从缓存中逐出子项,并允许您在没有参数的情况下调用 saveChanges() 。或者,您可以传递一个数组,其中包含您设置删除的记录。然后,您可能希望在保存后驱逐孩子。或者您可以停止使用该实体管理器。

于 2014-02-04T16:29:54.793 回答
1

支持级联删除是一个非常合理的要求。

请在此处添加对客户端级联删除支持的投票:Breeze User Voice。在确定要为 Breeze 产品添加哪些功能时,我们非常重视这个场所。

于 2013-04-26T17:59:34.080 回答