我注意到Breeze.js在删除尚未保留的实体(EntityState =“Added”)和持久化实体之间的任何引用(外键)之间存在令人厌烦的差异。
这可能是与为新实体生成临时密钥有关的问题。在这种情况下,我们为临时密钥(ID)生成负数,在持久化时用实际密钥替换。
通过具体的例子可以更容易地解释这一点。假设我们有一个名为Person的实体,它持有对Title实体的引用(“Mr”,“Mrs”等):
export class Person extends EntityBase {
id: number;
firstName: string;
lastName: string;
titleId: number;
title: Title;
...
}
export class Title extends EntityBase {
id: number;
name: string;
...
}
现在,如果我们在当前上下文中有一个持久化的Title实体并在其上调用.setDeleted(),那么适用的Person实体上的titleId属性和标题导航属性都将设置为null。
但是,如果Title实体的EntityState为“Added”,则只有所有链接的Person实体上的标题导航属性设置为null。 titleId属性保留其值,导致保存时出错(外键约束违规)。
这意味着删除EntityState为“Added”的Title实体需要为所有链接的Person实体显式设置titleId属性为null。
或许值得注意的是,底层数据库中的TitleID列可以为空。如果不是,我们当然必须将titleId属性设置为合适的值。
要做到这一点似乎很笨拙。这种行为是故意的,出于某种原因逃脱了我吗?
答案 0 :(得分:1)
在删除时,Breeze对
进行了重要区分对于已经存在的实体(案例b),Breeze必须跟踪该已删除的实体, 并将删除发送到服务器。必须更新服务器上的任何外键 删除对已删除实体的引用,以便breeze相应地更新相关的客户端实体 并将这些更改发送到服务器。
对于新创建的实体(案例a),服务器对此一无所知。几时
在客户端上“删除”,Breeze实际上没有设置它Deleted
,因为它没有
需要向服务器发送删除。相反,它将其设置为Detached
。
当实体设置为Detached
时,其导航属性将设置为null
从EntityManager的缓存中删除。它的外键属性没有改变,
但是,如果您分离实体并重新附加它,导航属性将会
重新连接。无论该实体是Added
还是之前的任何其他州,都是如此
它成了Detached
。
有关实体状态的更多信息,请参阅Breeze documentation
答案 1 :(得分:1)
我认为这实际上应该修改Breeze以更智能地处理Added
实体的删除。在此期间,以下可能代表一种解决方法(到目前为止我还没有机会尝试)。
首先,对于被删除的Added
个实体,问题似乎是引用该实体的导航属性不会更新以删除这些引用。也许有可能欺骗Breeze来照顾它。
Unchanged
。Added
,因此将删除转换为分离的逻辑将不适用。实体将其状态设置为Deleted
,并且将更新引用它的导航属性,以便它们不再执行。Deleted
的实体将是一个问题,因为会尝试删除实际上不存在的实体。将其状态设置为Detached以防止这种情况发生。因此,不要只是删除,而是尝试将状态设置为Unchanged
,然后删除并最终将状态设置为Detached
。