Breeze使用Guid PK删除父级,并修改子级

时间:2014-10-20 01:26:54

标签: angularjs entity-framework breeze

我正在尝试删除Angular / Breeze应用程序中的父实体和子实体。

后备存储是代码优先的实体框架。

实体如下:

public class Ingredient
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public virtual ICollection<IngredientDescription> Descriptions { get; set; }

}

public class IngredientDescription
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public Guid IngredientId { get; set; }

    [ForeignKey("IngredientId")]
    public virtual Ingredient Ingredient { get; set; }

    public string Description { get; set; }

    [Required]
    public int Culture { get; set; }
}

当我删除成分时,我需要删除IngredientDescription。我尝试过两种方式,我先删除(儿童,父母或父母,然后儿童)。

每当我删除I​​ngredient(父母)时,Breeze都会将孩子的IngredientDescription.IngredientId设置为Guid.Empty或{0000-0000 -...}。这导致子实体处于Modified状态(而不是已经设置了Deleted)。

我已经尝试了所有我能想到的东西,以便从客户端代码中实现这一点。我通过预览控制器中的更改并将其重新标记为已删除来使其工作。但是,我想从客户端开始工作。

我不必进行级联删除,只要我删除它,以防止Breeze将其从Deleted修改为Modified。

我的客户端功能如下:

        function removeIngredient(ingredient) {

        var descriptions = ingredient.descriptions;

        for (var d = 0; d < ingredient.descriptions.length; d++) {
            var thisDescription = ingredient.descriptions[d];
            thisDescription.entityAspect.setDeleted();
        }

        ingredient.entityAspect.setDeleted();

    }

在我已将Breeze标记为已删除后,如何保持Breeze将子对象标记为已修改?

下面是从removeFromRelations调用中将子节点的EntityState设置为修改的图像。

a busy cat http://s3.amazonaws.com/stack-overflow-tjb/problem.png

2 个答案:

答案 0 :(得分:2)

我认为问题出现在删除孩子的循环中

for (var d = 0; d < ingredient.descriptions.length; d++) {
    var thisDescription = ingredient.descriptions[d];
    thisDescription.entityAspect.setDeleted();
}

通过setDeleted()将记录设置为Deleted,记录将从数组中删除。因此,记录被删除以进行删除,然后在尝试保存父项时,FK违规即将发生。

我改变了以下的功能,并且长度为&gt; 0

    function removeIngredient(ingredient) {
        while (ingredient.descriptions.length > 0) {
            ingredient.descriptions[0].entityAspect.setDeleted();
        }

        ingredient.entityAspect.setDeleted();

    }

答案 1 :(得分:0)

好的,我刚刚重新测试了Breeze的删除逻辑(在微风版本1.5.0上)来尝试确认您的问题,并且无法重现您看到的行为。回顾一下,执行删除的顺序很重要。

  • 删除父级,然后删除子级

    • 这会将父标记为已删除,并会根据外键是否强制更新子项的外键为null或键的默认值财产是否可以为空。此规则的一个例外是breeze将永远不会尝试修改主键,因此如果子键的外键也是主键的一部分,则breeze不会尝试修改它。

    • 现在,所有子导航属性都将返回空数组或null,具体取决于导航属性是否为标量。此时,由于外键更改,每个孩子都会被标记为已修改

    • 然后,每个孩子都会被标记为已删除

  • 删除子项,然后删除父项(推荐)

    • 每个孩子都会被标记为已删除。外键不会更改,但相应的导航属性将返回null,而不是返回父项。此时,之前返回这些子节点的所有父导航属性现在将返回null或空数组。
    • 父母被标记为已删除。没有任何改变它的孩子(因为它现在没有)。

我无法重复将实体设置为已删除后修改的实体状态的情况。但是,这可能是早期版本Breeze中的一个错误,所以请尝试使用最新版本进行测试。