1

我们有一个具有三个关键字段的实体,其中一个是日期(不要问 - 它是一个没有其他明显键的摘要视图)。

在将更改保存到上述实体后处理来自服务器的响应时,Breeze 抛出“此密钥已附加”错误。

保存更改后, MergeEntity中会出现问题。似乎初始查找未能在客户端上找到实体,因此它尝试再次添加它导致错误。

在 MergeEntity 的顶部附近,我们发现以下行...

var entityKey = EntityKey._fromRawEntity(node, entityType);

...返回一个 entityKey._keyInGroup == "1535:::44::: 2013-02-28T11:00:00.000Z "。请注意看起来像 JSON 日期字符串的第三个关键字段。

后来,当新实体(错误地)创建其 entityKey._keyInGroup == "1535:::44::: Fri Mar 01 2013 00:00:00 GMT+1300 (New Zealand Daylight Time) "时。现在第三个字段看起来像一个真正的 JavaScript 日期。

当我们点击这条线时,错误终于发生了......

attachEntityCore(em, targetEntity, EntityState.Unchanged);

...获取“此密钥已附加”错误,因为我们刚刚保存的实体显然一直在客户端缓存中。


更新:我对 Breeze 的破解让这个工作......

1) 我更改了 _ fromRawEntity函数以检查日期并正确转换它们,以便我们获得稍后为真实实体生成的相同键值。(此代码是从updateEntity函数复制的,因此行为应该相同)。

ctor._fromRawEntity = function (rawEntity, entityType) {
    var keyValues = entityType.keyProperties.map(function (p) {
        var val = rawEntity[p.nameOnServer];
        if (p.dataType.isDate && val) {
            if (!__isDate(val)) {
                val = DataType.parseDateFromServer(val);
            }
        }
        return val;
    });
    return new EntityKey(entityType, keyValues);
};

2) Breeze 现在在保存更改后找到了实体,但是......当 Breeze 尝试使用从服务器返回的值更新实体属性时,我得到了一个错误。我怀疑这是由于defaultPropertyInterceptor函数中的一个问题,该函数正在检查属性值是否已更改...

// exit if no change
if (newValue === oldValue) {
    return;
}

比较日期时,这将始终返回 false,因此我将这一行修改为:

if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
    return;
}

从我最初的测试来看,一切似乎都在工作,但我非常感谢那些更熟悉微风的人的任何想法:)

更新:也许最后一个片段会更轻松,因为......

// exit if no change
var comparable = dataType && getComparableFn(dataType);
if (newValue === oldValue || (comparable && comparable(newValue) === comparable(oldValue))) {
    return;
}

...尽管考虑到它在每个属性集中运行,这增加了一些代码。

4

1 回答 1

0

编辑:这已在 Breeze v1.3.0 中修复,现在可用。


同意,这是一个错误!它将在下周初的下一个版本中修复。(我们现在有一个包含日期作为主键一部分的测试:)

并感谢您发现、分析和报告它。分析确实有帮助。

于 2013-04-13T19:34:20.480 回答