Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从ObservalArray中删除元素_C#_Javascript_Knockout.js_Entity Framework 5_Breeze - Fatal编程技术网

C# 从ObservalArray中删除元素

C# 从ObservalArray中删除元素,c#,javascript,knockout.js,entity-framework-5,breeze,C#,Javascript,Knockout.js,Entity Framework 5,Breeze,我有一个ASP.NET MVC应用程序,在客户端使用durandal、knockout.js和breeze。我有一个问题,我经常遇到,但我没有发现任何地方提到它。我不确定自己是否陷入了一个独特的境地,或者我只是没有找到正确的方法 我需要知道如何从ObservalArray中删除Breeze实体,以便提交成功(请参见下面的选项a),UI反映更改(请参见下面的选项B) 我有以下型号(缩写): 当我使用这种方法时,我从Breeze.WebApi中得到以下错误: Int32Converter无法从Sys

我有一个ASP.NET MVC应用程序,在客户端使用durandal、knockout.js和breeze。我有一个问题,我经常遇到,但我没有发现任何地方提到它。我不确定自己是否陷入了一个独特的境地,或者我只是没有找到正确的方法

我需要知道如何从ObservalArray中删除Breeze实体,以便提交成功(请参见下面的选项a),UI反映更改(请参见下面的选项B)

我有以下型号(缩写):

当我使用这种方法时,我从Breeze.WebApi中得到以下错误:

Int32Converter无法从System.Int64转换

我已经查看了堆栈,并检查了Breeze源代码(尽管我还没有配置解决方案来逐步完成),错误来自Breeze.WebApi.EFContextProvider::RestoreOriginal,它正在将原始属性值还原到对象。我不知道为什么它认为我的值是Int64,但我找不到一个好的解决办法,所以我试着

选项B

function deleteContact(contact){
    viewModel.donor().contacts.remove(contact);
    contact.entityAspect.setDeleted();
    viewModel.uow.commit();
}
function deleteContact(contact){
    contact.entityAspect.setDeleted();
    viewModel.uow.commit();
}

这种方法允许我成功地保存删除(因为该项尚未手动从集合中删除,因此没有任何“原始值”)。但是,这里的问题是
setDeleted
有效地从observableArray中删除该项,而不通知我的敲除绑定数组已更改。因此,该项目已被删除,但我的UI仍显示该项目。以后尝试调用
provider().contacts.remove(contact)
是徒劳的,因为observableArray不再包含该项目。

在使用选项b后,您是否尝试调用observableArray上的
valueHasMutated()


这将通知订阅者可观察对象已更改。

如果您“删除”或“分离”实体,Breeze将自动从任何导航集合中删除该实体。所以我会尝试消除

 viewModel.donor().contacts.remove(contact);  
行并查看单独调用“setDeleted”是否满足您的需要

TL:DR 切勿在createEntity的初始值设定项中设置FKs,同时将实体推送到父项的导航属性。保留其中一个,但不能同时保留两个

基本原则 在遇到类似问题并进行了大量调查之后,我想提出另一个答案。您正在试验的问题不是如何删除项目,而是如何创建项目

Breeze在管理其数据上下文方面非常有能力。它知道导航属性和外键以及如何处理它们。作为局部数据上下文的副作用,所有可观察对象也具有这种智能。这就是你可能忽略了一些东西而导致这个问题的地方

追踪breeze的代码 这一切具体意味着什么?有两种方法可以使用breeze创建具有父实体的对象。第一种方法是在初始值设定项中设置其父id,如下所示:

var c = manager.createEntity('contact', { 'donorId': 12, 'name': 'bob' });
另一种方法是将实体添加到数据上下文中父实体的导航属性中

var parents = ko.observableArray();
manager.runQuery(..., parents);

var c = manager.createEntity('contact', { 'name': 'bob'});
parents.contacts.push(c);
这两种情况各有利弊。当您尝试同时执行以下两种操作时,问题就会出现:

var parents = ko.observableArray();
manager.runQuery(..., parents);

var c = manager.createEntity('contact', { 'donorId': 12, 'name': 'bob' });
parents.contacts.push(c);
Breeze试图在处理插入时优化其查询,以防止UI闪烁。调用
push
时,它会禁用可观察目标的通知,直到整个操作完成。然后,它将在内部调用
valueHasMutated
,这将触发UI刷新。问题是,调用
createEntity
会干扰此机制,并导致通知过早重新初始化。然后,
推送
将保存此无效状态,交换并重置它,使可观察对象处于无效状态

当您最终调用
setDeleted
时,即使在breeze的数据上下文中正确推送了数据,observable上的通知仍将被禁用,从而阻止UI刷新。这只会在插入新元素后发生一次。删除元素将强制将状态更改为其正确的值,并且导航属性上的所有后续删除将触发UI刷新

看看你的两个选择
最后,您只需使用
setDeleted
即可从breeze导航属性中正确删除实体。无需手动将其从observable中删除,事实上,这样做会将外键重置为
null
,这可能会导致服务器上出现反序列化问题,如果该类型在模型中不可为null,或者根据主键的定义尝试从数据库中删除该行时出错。选项B是可以使用的。

在使用选项B之后,您是否尝试过在您的可观察数组上调用
valueHasMutated()
?我没有尝试过,而且确实有效,谢谢。继续添加一个答案——我很好奇是否有任何IdeaBrade的人对此有想法,所以我可能会让它开放一两天,看看他们是否会插话。还在想我是否是唯一一个出现转换器错误的人…Breeze应该知道吗?考虑:
var foo=ko.observearray([“A”]);foo.push(“B”)这将更新数组和DOM<代码>foo().push(“C”)此操作仅更新阵列。选项A做得对,但根据你的经验,选项B不行。这里有一个例子。您可以看到这些值被取消移动到每个数组,但只有一个更新了DOM。如果添加
vm.foo.valueHasMutated()
在应用绑定之后,DOM会同时更新这两个版本,这是这里发生的事情的简化版本,以及为什么会这样。@Dennis-是的,我相信Breeze知道。当我使用Breeze检索我的实体时,Breeze会将所有内容隐藏在幕后,这意味着我的实体上的所有属性要么是可观察的,要么是可观察的。因此,这是显而易见的
var parents = ko.observableArray();
manager.runQuery(..., parents);

var c = manager.createEntity('contact', { 'donorId': 12, 'name': 'bob' });
parents.contacts.push(c);