代码之家  ›  专栏  ›  技术社区  ›  Richard

调用保存更改时,Breeze外键导航属性未在保存捆绑包中发送

  •  4
  • Richard  · 技术社区  · 12 年前

    我在尝试通过微风保存一个新的儿童对象时遇到了问题,我的模型归结为

    Parent Foo有零个或多个bar类型的子对象,即Parent有一个名为bar的ICollection类型的属性,而bar对象有一个Foo类型的属性-其父对象

    我可以通过Breeze获取、更新和插入“父”Foo对象的新实例-这是使用web api控制器,但我在创建Bar的新实例、设置其父Foo(已经在缓存中)和调用保存更改时遇到了约束冲突

    我有类似的代码

    var newBar = entityManager.createEntity("Bar");
    newBar.Foo = existingFoo;
    entityManager.saveChanges();
    

    我也试着把孩子加入父母的收藏 现有Foo.bars.prush(newBar);

    并显式调用
    entityManager.addEntity(newBar);

    在调用save更改之前,但错误相同

    检查传递给控制器的JObject saveBundle,我可以看到新的子条对象,但没有看到任何对父对象的引用

    这是一种简单的一对多关系,我认为这是支持的吗?-我可以在元数据中看到看起来正确的关系

    异常消息如下所示

    “FooBarContext.Bars”中的实体参与“Foo_Bars”关系。找到了0个相关的“Foo_Bar_Source”。

    我做错了什么?

    更新1:控制器生成的元数据:

    “{\”schema“:{\“namespace\”:\”BreezePlayground.Models\“,\”alias\“:\”Self\“,\“d4p1:UseStrongSpatialTypes\”:\“false”,\“xmlns:d4p1\”:“” http://schemas.microsoft.com/ado/2009/02/edm/annotation \“,\”xmlns\“:\” http://schemas.microsoft.com/ado/2009/11/edm \“,\”cSpaceOSpaceMapping\“:\”[[\\“BreezePlayground.Models.Foo\\”,\\“BrezePlayground.Models.Foo\\”],[\\“BreezePlayground.Models.Bar\\”,\\“BreezyPlayground.MModels.Bar\\“]]\”,\“entityType\”:[{\”name \“:\”Foo\“,\”key \“:{\“propertyRef\”:{\”name \”:\“Id \”}},\“property \”:【{\”name \:\“Id\”,“type \”:“Edm.Int32\”,\”nullable \“:”false\“,”d4p1:StoreGeneratedPattern\“:\”Identity\“},{\”name\“:\“name\”,\”type\“:”Edm.String\“,\”fixedLength“:”false\“,”maxLength\“:“Max\”,“unicode”:\“true\”,\“nullable\”:\”true\“}],\“navigationProperty\”:{\“name\”:\“Children”,\“relationship\”:“Self.Bar_Parent\”,\”fromRole\“:\”Bar_Parent_Target\“,\”toRole\“”:\”Bar_Parent_Source\“}},{\”name\“:”Bar\“,”key\“:{”propertyRef\“:\“Edm.Int32\”,\“nullable\”:\“false\”,\”d4p1:StoreGeneratedPattern\“:\”Identity \“},{\”name \“:”Description \“,\”type \“:“Edm.String\”,“”fixedLength\“:\”false\“,\”maxLength“:\“Max\”,\“unicode\”:\“true\”,\”nullable\“:”true\“}],\“navigationProperty\”:{\“name\”:“Parent\”,“relationship\”:\Self.Bar_Parent\“,\fromRole\”:\\“Bar_Parent_Source\”,\toRole\“:\\”Bar_PareNTarget\“}】,\“association\”:,\“end\”:[{\”role\“:\”Bar_Parent_Source\“,\”type\“:\“Edm.Self.Bar\”,\“multiplicity\”:\“*\”},{\“role\”:\Bar_Parent_Target\“,\”type\“:\”Edm.Self.Foo“,\“multiplicity \”:\“0..1\”}]},\“entityContainer\”:{\“name \”:“FooBarContext\”,\“实体集\”:[{\”name \“:”Foos \“,”entityType \“::\”Self.Foo \“},{\“name \”:\“Bar_Parent\”,\“association \”:“Self.Bar_PParent\”、\“end\”:[{\”role\“:\”Bar_Parent_Source\“,\”entitySet\“:\“Bars\”},{\“role\”:\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');
            });
        });
    

    生成的请求有效载荷:

    {“实体”:[{“Id”:-1,“Description”:“bar desc”,“entityspect”:{“entityTypeName”:“bar:#BreezePlayground.Models”,“实体状态”:“已添加”,“原始值映射”:{

    插入了子对象,但未设置外键

    我假设这与ef映射和生成的元数据有关?

    更新2:是否需要外键属性?

    我将我的代码与新的Breeze SPA模板ToDo应用程序代码进行了比较,后者显然有效,我在生成的元数据中发现的关键区别是ToDo应用模型公开了父对象外键。

    我将其添加到我的简单Foo-Bar模型中,并能够使子对象的保存生效-我的理解是,ef使得在模型中公开外键是可选的,但这似乎是Breeze生成正确元数据的要求?-我是不是在什么地方的医生那里错过了?

    1 回复  |  直到 12 年前
        1
  •  4
  •   Ting    12 年前

    抢手货我们确实需要更好地记录这一点,因此这篇文章正在更新关于这个主题的文档。

    正如您所发现的,微风假设您使用的是“外键关联”,而不是“独立关联”(用EF的说法)。

    这一要求可以绕过,但功能会有很大损失,原因是客户端上存在外键,这使得微风能够自动修复可能单独查询的实体之间的关系。

    有关更多背景信息,请参阅以下MSDN文章: foreign-keys-in-the-entity-framework