升级BreezeJS至v2.1.4后多对多实体保存触发Fixup错误
BreezeJS v2.1.4多对多关联保存时键修复报错的解决方案
1. 检查连接实体的元数据配置
多对多连接实体必须正确配置复合键,且需明确告知Breeze它是关联实体而非复杂类型:
- 确保连接实体(如
Join)的元数据中,两个外键属性(dependentId、principalId)都标记为isPartOfKey: true - 确认
isComplexType设置为false(默认值为false,但如果之前有特殊配置需检查)
示例元数据配置片段:
{ "name": "Join", "shortName": "Join", "namespace": "YourNamespace", "isComplexType": false, "dataProperties": [ { "name": "dependentId", "dataType": "Int32", "isPartOfKey": true }, { "name": "principalId", "dataType": "Guid", "isPartOfKey": true } ], "navigationProperties": [ { "name": "dependent", "entityTypeName": "Dependent:#YourNamespace", "foreignKeyNames": ["dependentId"] }, { "name": "principal", "entityTypeName": "Principal:#YourNamespace", "foreignKeyNames": ["principalId"] } ] }
2. 调整客户端实体创建逻辑(推荐)
不要再手动创建连接实体并设置临时id,改用Breeze的导航属性自动管理关联,这能避免手动键映射导致的冲突:
const dependent = entityManager.createEntity('Dependent', { containerId: 113, title: 'Test dependent entity' }); // 获取已存在的主体实体 const principal = entityManager.getEntityByKey('Principal', 'ad3f84bb-ae38-4125-b73c-3cb5cbb88c04'); // 通过导航属性关联,Breeze会自动创建并管理连接实体 dependent.principals.push(principal); await entityManager.saveChanges();
这种方式下,Breeze会自动处理临时键到真实键的映射,无需手动干预连接实体的键值。
3. 服务器端优化键映射返回
如果必须手动创建连接实体,需确保服务器返回的keyMappings仅包含Dependent实体的临时键→真实键映射,不要返回Join实体的键映射(因为它的复合键依赖于Dependent的真实键,服务器保存时应自动更新Join.dependentId,无需单独返回其键映射)。
检查服务器端Breeze的保存逻辑,确认多对多连接实体的键映射不会被额外返回。
4. 临时修复:手动处理键映射
如果上述方案暂时无法实施,可在保存前通过实体关联替代手动设置外键,让Breeze自动处理键值:
const dependent = entityManager.createEntity('Dependent', { containerId: 113, title: 'Test dependent entity' }); const join = entityManager.createEntity('Join', { // 先不设置dependentId,通过导航属性关联 principalId: 'ad3f84bb-ae38-4125-b73c-3cb5cbb88c04' }); // 建立实体关联,Breeze会自动管理外键值 join.dependent = dependent; await entityManager.saveChanges();
内容的提问来源于stack exchange,提问作者Tim Coulter
相关产品推荐
相关产品推荐

