Breeze.js-删除新(EntityState=“添加的”)实体时未清除外键

Breeze.js-删除新(EntityState=“添加的”)实体时未清除外键,breeze,Breeze,我注意到Breeze.js中删除一个尚未持久化的实体(EntityState=“Added”)和一个关于它的任何引用(外键)的持久化实体之间存在着令人讨厌的差异 这可能是与为新实体生成临时密钥有关的问题。在本例中,我们为临时键(ID)生成负数,当它们被持久化时,替换为实际键 这将更容易用一个具体的例子来解释。假设我们有一个名为Person的实体,该实体包含对所有权实体的引用(“Mr”、“Mrs”等): 现在,如果我们在当前上下文中有一个持久化的Title实体,并对其调用.setDeleted()

我注意到Breeze.js中删除一个尚未持久化的实体(EntityState=“Added”)和一个关于它的任何引用(外键)的持久化实体之间存在着令人讨厌的差异

这可能是与为新实体生成临时密钥有关的问题。在本例中,我们为临时键(ID)生成负数,当它们被持久化时,替换为实际键

这将更容易用一个具体的例子来解释。假设我们有一个名为Person的实体,该实体包含对所有权实体的引用(“Mr”、“Mrs”等):

现在,如果我们在当前上下文中有一个持久化的Title实体,并对其调用.setDeleted(),则适用的Person实体上的titleId属性和Title导航属性都设置为null

但是,如果标题实体的EntityState为“Added”,则只有所有链接的个人实体上的标题导航属性设置为null。titleId属性保留其值,导致保存时出错(外键约束冲突)

这意味着删除EntityState为“Added”的标题实体需要将所有链接的个人实体的titleId属性显式设置为null

可能值得注意的是,底层数据库中的TitleID列可以为null。如果不是,我们当然必须将titleId属性设置为合适的值


不得不这样做似乎很笨拙。这种行为是故意的吗?出于某种我无法理解的原因?

说到删除,Breeze在

  • (案例a)仅存在于客户端上的实体(处于添加状态的实体),以及
  • (案例b)已在服务器上持久化的实体
对于已持久化的实体(案例b),Breeze必须跟踪已删除的实体, 并将删除内容发送到服务器。必须更新服务器上的所有外键 删除对已删除实体的引用,以便breeze相应地更新相关的客户端实体 并将这些更改发送到服务器

对于新创建的实体(案例a),服务器对此一无所知。当它是 在客户机上的“已删除”,Breeze实际上没有将其设置为“已删除”,因为它没有 需要向服务器发送删除。相反,它将其设置为“分离”

当实体被设置为分离时,其导航属性被设置为空,并且 从EntityManager的缓存中删除。它的外键属性没有改变, 但是,如果拆离实体并重新附着它,则导航属性将 重新连接。无论实体是
添加的
还是之前的任何其他状态,都是如此 它变成了分离的


关于实体状态的更多信息可以在

中找到,我认为这实际上是一种情况,Breeze应该被修改,以更智能地处理添加的实体的删除。但同时,以下可能是一种解决方法(到目前为止,我还没有机会尝试)

首先,对于已删除的添加的实体,问题似乎是引用该实体的导航属性不会更新以删除这些引用。也许可以诱使微风来照顾这件事

  • 首先将要删除的添加实体的状态设置为类似于
    未更改的状态
  • 删除实体。由于实体的状态不再是添加的,因此将删除转换为分离的逻辑将不适用。实体的状态将设置为“已删除”,引用该实体的导航属性将被更新,以便它们不再这样做
  • 将实体保留为“已删除”状态将是一个问题,因为会有人试图删除实际上不存在的实体。将其状态设置为“已分离”以防止出现这种情况

  • 因此,不要只是删除,试着将状态设置为
    未更改
    ,然后删除,最后将状态设置为
    分离

    ,这在EntityState为Added的实体上调用setDetached()时是有意义的,但在实体上调用setDeleted()时,它是非常明确的-您是说要将其删除。是的,在幕后微风只是拆开它,但留下的外键引用它似乎草率对我来说。在什么可能的情况下,将这些键(现在引用的是一个永远不存在的实体)留在后面会有用呢?我同意@ToboldHornblower。仅仅将添加实体的删除视为分离,就有点过于简单了。如果我正在删除,那是因为我不希望数据库中有该实体。如果实体的记录不在数据库中,那么引用它的外键总是会有问题。在删除过程中,应清除它们所基于的导航属性。理想情况下,微风会照顾到这一点。作为替代,我们有没有办法手动处理?以某种方式钩住用于删除的逻辑?
    export class Person extends EntityBase {
        id: number;
        firstName: string;
        lastName: string;
        titleId: number;
        title: Title;
        ...
    }
    
    export class Title extends EntityBase {
        id: number;
        name: string;
        ...
    }