我在尝试通过微风保存新的子对象时遇到问题,我的模型归结为此
Parent Foo有零个或多个bar类型的子对象,即Parent有一个名为bars的ICollection类型的属性,而Bar对象有一个Foo类型的属性 - 它的父
我可以通过Breeze获取,更新和插入“父”Foo对象的新实例 - 这是使用web api控制器但是在创建Bar的新实例时设置其父Foo(已经在缓存)并调用保存更改
我的代码与此相似
var newBar = entityManager.createEntity("Bar");
newBar.Foo = existingFoo;
entityManager.saveChanges();
我也尝试将孩子添加到父母集合中,例如 existingFoo.bars.push(newBar);
并明确呼叫
entityManager.addEntity(newBar);
但错误是相同的
检查传递给控制器的JObject saveBundle我可以看到新的子栏对象,但是我看不到对父对象的任何引用
这是一个简单的一对多关系,我认为是支持的? - 我可以看到元数据中看起来正确的关系
异常消息如下所示
'FooBarContext.Bars'中的实体参与'Foo_Bars'关系。找到了0个相关的'Foo_Bar_Source'。
我做错了什么?
“{\” 模式\ “:{\” 命名空间\ “:\” BreezePlayground.Models \ “\ ”别名\“:\ ”自\“,\ ”d4p1:UseStrongSpatialTypes \“:\” 假\ ” \ “的xmlns:d4p1 \”:\ “http://schemas.microsoft.com/ado/2009/02/edm/annotation \”,\ “的xmlns \”:\ “http://schemas.microsoft.com/ado/2009/11/edm \”,\ “cSpaceOSpaceMapping \”:\ “[[\\” BreezePlayground .Models.Foo \\ “\\ ”BreezePlayground.Models.Foo \\“],[\\ ”BreezePlayground.Models.Bar \\“,\\ ”BreezePlayground.Models.Bar \\“]] \”, \ “的EntityType \”:[{\ “名称\”:\ “富\”,\ “键\”:{\ “propertyRef \”:{\ “名称\”:\ “ID \”}},\”属性\ “:[{\” 名称\ “:\” ID \ “\ ”类型\“:\ ”Edm.Int32 \“,\ ”为空的\“:\ ”假\“,\” d4p1:StoreGeneratedPattern \ “:\” 身份\ “},{\” 名称\ “:\” 名称\ “\ ”类型\“:\ ”Edm.String \“,\ ”定长\“:\ ”假\“,\”最大长度\ “:\” 最大\”,\ “统一\”:\ “真正\”,\ “为空的\”:\ “真正\”}],\ “navigationProperty \”:{\ “名称\”:\ “孩子\”,\ “关系\”:\ “Self.Bar_Parent \”,\ “fromRole \”:\ “Bar_Parent_Target \”,\ “toRole \”:\ “Bar_Parent_Source \”}},{\“名称\ “:\” 酒吧\”,\ “键\”:{\ “propertyRef \”:{\ “名称\”:\ “ID \”}} \ “属性\”:[{\ “名称\”: \ “ID \”,\ “类型\”:\ “Edm.Int32 \”,\ “为空的\”:\ “假\”,\ “d4p1:StoreGeneratedPattern \”:\“标识两者均\ “},{\” 名称\ “:\” 描述\” \ “类型\”:\ “Edm.String \”,\ “定长\”:\ “假\”,\ “最大长度\”: \ “最大\”,\ “统一\”:\ “真正\”,\ “为空的\”:\ “真正\”}],\ “navigationProperty \”:{\ “名称\”:\ “父\” ,\ “关系\”:\ “Self.Bar_Parent \”,\ “fromRole \”:\ “Bar_Parent_Source \”,\ “toRole \”:\ “Bar_Parent_Target \”}}],\ “协会\”:{\ “名称\”:\ “Bar_Parent \”,\ “端\”:[{\ “角色\”:\ “Bar_Parent_Source \” \ “类型\”:\ “Edm.Self.Bar \”,\“多重\ “:\” * \ “},{\” 角色\ “:\” Bar_Parent_Target \ “\ ”类型\“:\ ”Edm.Self.Foo \“,\ ”多重\“:\” 0 .. 1 \ “}]},\” EntityContainer相关\ “:{\” 名称\ “:\” FooBarContext \ “\ ”EntitySet的\“:[{\ ”名称\“:\ ”FOOS \“ \” 的EntityType \ “:\” Self.Foo \ “},{\” 名称\ “:\” 条\ “\ ”的EntityType \“:\ ”Self.Bar \“}],\ ”associationSet \“:{\” 名\ “:\” Bar_Parent \”,\ “关联\”:\ “Self.Bar_Parent \”,\ “端\”:[{\ “角色\”:\ “Bar_Parent_Source \”,\ “EntitySet的\”:\ “条\”},{\ “角色\”:\ “Bar_Parent_Target \”,\ “EntitySet的\”:\ “FOOS \”}]}}}}“
示例代码:
var managerInsert = new breeze.EntityManager("/api/FooBar");
managerInsert.fetchMetadata().then(function () {
managerInsert.fetchEntityByKey('Foo', 1, false)
.then(function (data) {
var child = managerInsert.createEntity('Bar');
child.Parent(data.entity);
child.Description("bar desc");
managerInsert.saveChanges().then(function () {
return true;
})
.fail(function () {
alert('save failed');
});
})
.fail(function (data) {
alert('fail');
});
});
生成的请求有效负载:
{“entities”:[{“Id”: - 1,“Description”:“bar desc”,“entityAspect”:{“entityTypeName”:“Bar:#BreezePlayground.Models”,“entityState”:“已添加”, “originalValuesMap”:{}, “autoGeneratedKey”:{ “PROPERTYNAME”: “ID”, “autoGeneratedKeyType”: “同一性”}}}], “saveOptions”:{ “allowConcurrentSaves”:假}}
插入子对象但未设置外键
我假设这与ef映射和生成的元数据有关吗?
我将我的代码与新的Breeze SPA模板ToDo应用程序代码进行了比较,该代码明显有效,我在生成的元数据中发现的主要区别是ToDo应用程序模型公开了父对象外键。
我将它添加到我的简单Foo Bar模型中并且能够保存子对象的工作 - 我的理解是,ef使得它可以在模型中公开外键,但似乎这是一个要求Breeze为了生成正确的元数据? - 我在某个地方的文档中错过了吗?
答案 0 :(得分:4)
好抓!我们确实需要更好地记录这一点,并且由于这篇文章正在更新有关该主题的文档。
正如您所发现的那样,微风假设您使用的是“外键关联”而不是“独立协会”(用EF的说法)。
此要求的原因是可以绕过但功能大量丢失,因为客户端上存在的外键允许breeze自动修复可能单独查询的实体之间的关系。
有关更多背景信息,请参阅以下MSDN文章:foreign-keys-in-the-entity-framework