0

在我的水疗中心,我需要向客户端发送一个复杂的对象树并让用户填写他的数据,然后才能将实体保存在数据库中。因此,此时实体不存在于数据库中。对象树在服务器的内存中构建,只需调用breeze.EntityQuery.from("ComplexeObjectTree"). 实体通过剔除绑定到 Web 表单。用户首先输入所需的数据,然后才能按下保存按钮。表单中的一些实体属性是可选的并且具有默认值。如果用户不更改这些属性,beeze 将不会检测到任何更改并且不会将其拥有的实体放入更改集中。它们被标记为不变,但它们的 id 值仍然是-1(尚未保存)。但是只有当对象树中的所有实体(包括它们的关系)都已发送到服务器(以尊重数据库约束)时,才能成功执行数据库保存。保存操作应该产生一个或多个插入语句,对于那些在客户端没有更改但对数据库来说是新的实体 ( id==-1) 也是如此。我该如何处理这个用例?主键标记为已添加的所有实体不应该id==-1默认成为保存更改集的一部分吗?

很感谢任何形式的帮助,

安德烈亚斯

4

3 回答 3

1

通常,您会在客户端而不是服务器上创建实体。这样,实体是新的,将保存在 save 方法中。

由于实体来自服务器并且它们没有在客户端上被更改,因此当它们返回时服务器没有理由对它们做任何事情,因为它们处于与它们离开时相同的状态。

因此,在客户端上创建新实体,然后调用保存更改。

于 2013-01-25T15:46:16.887 回答
1

让我们按照您的方式进行,并接受您的要求,即对象图必须在服务器上构建。如果我理解正确,您是在为用户提供机会,在将它们提交到永久存储之前调整您在服务​​器上生成的一些值。听起来是个不错的计划。

“ComplexObjectTree”不必是实体图。它可以是任意数据对象。它仍然可以是 CLR 类型,但不会是(或包含)元数据中描述的对象,EF 或 Db 也不会知道它们。该对象图仅作为驱动在客户端构建真实实体图的信息而存在。它包含所有你不想在客户端计算的难以计算的值……比如生命意义的答案以及今年谁赢得了超级碗。

您的查询返回此对象,其中包含数据但没有实体。querySuccess 回调CreateComplexTree(data)使用此数据制作客户端上的实体图

由于元数据,实体图将由 Breeze 客户端理解的实体组成。除非您有异议,否则这些实体也会在服务器上被理解,并且可以像任何其他实体一样保存和查询(如果为假,您可以绕过该假设......但让我们一次解决一个问题)。

所以你都准备好了。您遍历数据图,边走边创建实体。当您在数据中看到 (-1) 时,您就知道要创建该类型的新实例。将数据复制到实体初始化对象中,该对象是manager.createEntity('Foo', {...}). 这里没有业务逻辑 - 没有计算 - 只是复制的猴子工作。

我不知道是要插入图表中的每个对象还是只插入其中一些对象。也许其中一些是预先存在的实体,除非用户也更改它们,否则它们不会改变。没什么大不了的。您可以按照相同的方法在客户端上使用类似manager.createEntity('Bar', {...}, breeze.EntityState.Unchanged).

现在您有了一个合适的 Breeze 实体图,可以进行绑定、导航和保存。如果用户喜欢服务器创建它的方式,她按下 [保存] 按钮,Breeze 会在实体图中找到所有更改,然后将它们转到服务器。

正如 Bryant 所观察到的,你不能真正信任客户。您需要遍历图表来验证它。但不管你的方法是什么,这都是真的。

希望这可以帮助。

于 2013-01-25T19:26:06.320 回答
0

科比完全正确的是他的回答。这个答案只是为了得到澄清。

不完全确定我理解这个问题,但只是为了清楚微风 EntityManager 不支持具有相同“键”的多个相同类型的实体(即在您的情况下为-1)。它将具有相同键的单一类型的所有实体视为“相同”实体。

听起来您想要做的是将一堆“假”实体检索到 entityManager 中,然后有条件地将其中一些转换为“真实”实体并保存它们,从而将这些记录添加到数据库中。这是你想要完成的吗?

于 2013-01-25T18:34:20.250 回答