【问题标题】:"Only entities in this entityManager may be saved" when deleting a breeze entity while subscribed to entityChanged event handler在订阅 entityChanged 事件处理程序时删除微风实体时,“只能保存此 entityManager 中的实体”
【发布时间】:2014-09-03 19:48:09
【问题描述】:

我有一个多对多关系的映射表。我订阅了 entityChanged 事件,并在处理程序中调用了 saveChanged。当我单击 kogrid 行时,会调用一个单击事件处理程序,从 krid 和数据库中删除当前记录。

问题是我在 saveChanged 失败时收到 “仅此 entityManager 中的实体可以保存” 消息,尽管该记录实际上已从数据库中删除。实体的接口定义如下:

export interface TenantMemberLinkBreeze extends breeze.Entity
{
    TenantMemberId: KnockoutObservable<System.IGuid>; 
    MemberId: KnockoutObservable<System.IGuid>;
    TenantId: KnockoutObservable<System.IGuid>;
    InviterId: KnockoutObservable<System.IGuid>;
    Status: KnockoutObservable<string>;
    CreatedOn: KnockoutObservable<Date>; 
    Inviter: KnockoutObservable<User>;
    Member: KnockoutObservable<User>;
    Tenant: KnockoutObservable<Tenant>;
}

钻研微风源代码,我看到在getEntitiesToSave函数中有一个比较,如果实体的entitymanager与函数参数em相同。这就是异常发生的地方。看起来实体已与上下文分离(e.entityAspect.entityManager 为空)。 JavaScript 代码:

function getEntitiesToSave(em, entities) {
    var entitiesToSave;
    if (entities) {
        entitiesToSave = entities.filter(function (e) {
            if (e.entityAspect.entityManager !== em) {
                throw new Error("Only entities in this entityManager may be saved");
            }
            return !e.entityAspect.entityState.isDetached();
        });
    } else {
        entitiesToSave = em.getChanges();
    }
    return entitiesToSave;
}

entityChanged 的​​事件处理程序被触发 6 次:

  • AttachOnQuery(实体状态不变)
  • PropertyChanged(导航属性 1 设置为 null,entityState 变为 Deleted
  • PropertyChanged(导航属性 2 设置为 null,entityState 已删除
  • PropertyChanged(导航属性 3 设置为 null,entityState 已删除
  • EntityStateChange
  • 分离(envityState 变为分离)

entityChanged 事件处理程序(TypeScript):

this.SubscriptionKey = this.BreezeEntityManager.entityChanged.subscribe((data: breeze.EntityChangedEventArgs) => {
    if (data.entityAction === breeze.EntityAction.PropertyChange) {
        return setTimeout(() => {
            this.BreezeEntityManager.saveChanges(<breeze.Entity[]> new Array(data.entity))
                        .fail((error) => toastr.error("Failed. (more info: " + error + ")"));
                }, 0);
            }
        });

触发删除的代码(事件处理程序)(TypeScript):

return this.BreezeEntityManager.fetchEntityByKey("TenantMemberLink", tenantMemberLinkId)
.then((data: breeze.EntityByKeyResult) =>
    {
       data.entity.entityAspect.setDeleted();
    }

所以在我看来,在提交所有更改之前实体已分离,但我不知道再去哪里搜索。你有什么想法吗?

编辑: 更改后问题就消失了:

 this.BreezeEntityManager.saveChanges(<breeze.Entity[]> new Array(data.entity))

进入:

this.BreezeEntityManager.saveChanges()

这是一种解决方法,但我正在尝试理解这种(对我来说出乎意料的)行为。

【问题讨论】:

  • 您要传入新的实体数组的实体是什么?
  • 我在问题描述中添加了相关实体的实体接口

标签: javascript entity-framework typescript breeze


【解决方案1】:

这可能是您的 setTimeout 调用的时间问题。您是否有可能多次尝试“删除”同一个实体?如果是这样,第一次删除将分离实体,这将导致第二次删除失败并出现此错误。

当您在没有任何参数的情况下调用 saveChanges 时问题消失的事实支持了这一假设,因为该调用仅尝试保存尚未保存的实体。

为了调试它,我会用另一个函数包装你失败的 saveChanges 调用,该函数在你调用微风的 saveChanges 方法之前检查每个实体的状态并查看哪个实体/entityAspect 有一个空的 entityManager 属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多