Breeze在保存到服务器后在本地缓存中创建重复实体

Breeze在保存到服务器后在本地缓存中创建重复实体,breeze,Breeze,我遇到了与中描述的相同的问题,但是自从修复后,该问题被报告为由错误引起。我使用的是v1.4.11 我发现,当我将一个新的Breeze实体保存到服务器时,它会通过创建一个新的、重复的实体来响应服务器的成功响应,而不是更新现有的实体。我在浏览器控制台中逐行运行下面的测试代码,在Breeze的缓存中没有实体 EntityManager.createEntity("CustomGroup", properties); EntityManager.getChanges(); => 0:

我遇到了与中描述的相同的问题,但是自从修复后,该问题被报告为由错误引起。我使用的是v1.4.11

我发现,当我将一个新的Breeze实体保存到服务器时,它会通过创建一个新的、重复的实体来响应服务器的成功响应,而不是更新现有的实体。我在浏览器控制台中逐行运行下面的测试代码,在Breeze的缓存中没有实体

EntityManager.createEntity("CustomGroup", properties);
EntityManager.getChanges(); =>
    0:
        Id="b0cb3194-35af-4d23-9e77-d192c907b566"
        EntityState=Added
到目前为止,一切顺利。正如所料,挂起的更改数组中只有一个实体

EntityManager.saveChanges(); =>
    KeyMappings:
        0:
            TempValue="b0cb3194-35af-4d23-9e77-d192c907b566"
            RealValue="f056f519-9f11-4375-a0dd-5272a11b9b46"
在执行saveChanges()之后,服务器返回一个带有临时键值和实际键值的KeyMapping对象。此时,列出缓存中的所有实体将显示一个意外结果:

EntityManager.getEntities(); =>
    0:
        Id="f056f519-9f11-4375-a0dd-5272a11b9b46"
        EntityState=Added
    1:
        Id="b0cb3194-35af-4d23-9e77-d192c907b566"
        EntityState=Unchanged
因此,虽然Breeze将原始对象的状态更改为“未更改”,以响应保存到服务器的请求,但它没有使用新密钥对其进行更新,而是使用新密钥创建了一个重复实体,它认为仍然需要保存该实体


第二次调用saveChanges()会向服务器发送一个新的请求,服务器会用一个具有相同TempValue和RealValue的KeyMapping对象进行响应,此时Breeze决定不再进行任何更改,尽管恶意实体当然仍保留在缓存中。

我查看了您的Metadata.json,我认为问题就在那里。OData元数据有时不能提供足够的信息。在这种情况下,我认为Breeze客户端不知道ContentGroup有一个自动生成的密钥


我们通常建议在服务器上使用WebApi Breeze ContextProvider和BreezeControllerAttribute而不是OData。有关更多原因,请参阅

好的,我已经弄明白了。服务器在SaveChanges的响应中返回的实体具有临时键值,而它应该具有新的服务器生成的值。我注意到了这一点,但我认为这是正确的行为,Breeze会在收到响应后使用KeyMapping进行分类


在Breeze.ContextProviderEF6.EFContextProvider.cs中,我看不到任何修改提交实体键值的内容,因此这可能是EntityFramework中自动发生的事情,但我们需要在自定义LightSpeed ContextProvider中手动执行此操作。

是否可以使用DocCode模型之一创建重新单元测试(可在微风+样品拉链中找到)?.到目前为止,我无法重新处理您的问题。我无法复制DocCode示例的问题,但我在这里制作了一个非常简单的演示:。只需通过本地web服务器运行此演示。我已为元数据放入静态JSON文件并模拟SaveChanges的响应;这两个文件都是从真实的服务器响应复制而来的这是我从完整的.NET Web API项目中获得的。单击链接可将相关对象和详细信息记录到浏览器控制台,以显示在创建实体并将该实体保存到服务器之前和之后Breeze的缓存发生了什么。我们在早期遇到了自动生成密钥的问题,因此我们在dataservice.js中有此代码在客户端设置它:
var types=metadataStore.getEntityTypes();for(类型中的var i){types[i].autoGeneratedKeyType=breeze.autoGeneratedKeyType.Identity;}
所以我认为这不是问题所在。(我注意到我无意中在示例代码中遗漏了这个注释,但我只是在它处于活动状态时再次检查)。另外,我们已经在使用Web API Breeze ContextProvider和BreezeControllerAttribute,因此我们不确定为什么必须设置autoGeneratedKeyType。啊,对不起。如果您先使用代码,我认为您需要在Id属性上添加注释:[DatabaseGenerated(DatabaseGenerateOptions.Identity)]以使其出现在元数据中。太好了,谢谢Steve,这似乎确实起到了作用。不过,我们仍然遇到了重复实体的问题。