2010-01-22 77 views
3

我有一个MVC2应用程序,我开始使用STE的。我正在寻找关于更新应该如何工作的一些说明。自我跟踪实体(STE)和EF4和mVC2的部分更新

背景:

如果我有相关的类别实体和相关岗位/评论实体博客实体。在MVC中,我使用主Blog实体和类别呈现视图,但不显示相关帖子。当我将博客实体回发到服务器时,我可以看到相关类别,但是在被序列化回服务器的实体中看不到帖子(因为它们不在视图中)。此外,博客实体的更改状态为“已添加”。

然后我尝试拨打此博客实体上的Applychanges()SaveChanges()来执行更新,并且由于FK与帖子的关系以及数据库中存在相关帖子但未附加到实体的事实而失败送回。

随着一些进一步的测试...如果我连接到服务器(状态=不变)时抓取博客实体的当前实例(与所有相关的FK实体),修改一个属性(状态=修改)并更新它按预期工作。

所以我的问题: 如果我有相关的未被呈现在视图中,因此不回来后与博客实体应该更新实体机构开展工作?

为什么博客实体会以“已添加”状态发回而不是“已修改”?我会假设它会返回所有已更改实体的“修改”更改状态,然后当我调用ApplyChanges/SaveChanges()时,只有修改的项目会尝试更新,这就是为什么我不需要所有相关实体的原因。

我应该能够直接从客户端传递实体,还是应该将实体回传给服务器,从数据库中抓取现有副本,将更改应用到该副本,然后将现有对象发回?

回答

1

关于你的第一个问题:

然后我试图在这个博客上实体调用Applychanges()和 的SaveChanges()来 的执行更新,也未能 因为 的FK关系帖子和数据库中有 相关帖子,但不是 附加到我发送 回来的实体。

这可能是由您的第二个问题(“已添加”状态而不是“已修改”)引起的。上下文可能试图添加博客而不是试图保存更改,因此FK约束错误。

至于你的第二个问题:

为什么“修改”博客实体GET后回 与“新增”状态,而不是

?我相信它会 回来了“修改” changedstate所有更改的实体 ,然后当我打电话 ApplyChanges /调用SaveChanges()只有 修改的项目将尝试更新 ,这就是为什么我不需要所有 相关实体。

是“您使用的生成服务器和客户端代码相同的类型”来考虑问题?当您使用数据服务元数据生成类型时,STE已经为known to not keep track of changes。对于STE,有一段代码在构造函数中被激活,不会持续通过元数据生成的类型,因此是导致此问题的原因。

至于你最后quesiton:

我应该可以直接从客户端传递一个实体 和 ApplyChanges()/调用SaveChanges(),还是应该 我要回发到服务器 实体,从 数据库中抓取现有的副本,将该更改应用到 副本,然后发布现有的 对象?

是的,这是可能的(我已经测试了这一点),以ApplyChanges()/调用SaveChanges()直接来自客户端,无论在哪里实体最初是从(从服务器传来的实体进行修改或创建在客户端上作为新的实体添加)。

+0

我打算将此标记为答案,因为您确实提供了一些相关的良好反馈。但总体回答是,这不会像我预期的那样使用MVC。我收到了迭戈维加在EF小组解释原因的回复。这里是他的回应链接: http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/cecdc8b4-3e1f-46ec-93fe-fd44f42fea9c/#fb8a242b-c8f2-4ac2-a28c- 4b948cac8c8c – Jay 2010-03-10 14:37:39

0

我们非常相似的问题 - 周围的更新挣扎。根据我们的信息,我们收集到STE尚未准备好生产,但确实考虑过使用它们。

无论如何,这里的问题集中在附加和分离之间的区别,以及ObjectStateManager和STE之间的相互作用......在你描述的那个例子中,它起作用,因为它一直附着在STE上,从未实际转换到使用其STE行为(这只发生在反序列化到客户端之后,或者它们被重新连接到连接的实体)。

在回答他们为什么显示为补充:

例如,当国营被实例化,更改跟踪被停用,并在变更跟踪器的默认状态添加。

我发现这一切令人困惑,并采访了Julia Lerman,并在线发帖,似乎表明目前的STE版本还没有准备好现实世界......

见迭戈维加(EF队)这种反应

当您在此模式下使用国营贸易公司,他们大致表现为纯POCO对象。例如,您可以直接操作图形或使用ObjectContext和ObjectStateManager中的API,并且必须调用DetectChanges以确保在调用SaveChanges之前状态管理器在任何时刻都与图形同步。

最重要的是,标准对象服务API不知道STE,因此,诸如AcceptAllChanges(在您的示例中,它在SaveChanges期间隐式调用,并将投诉对象的ObjectStateManager状态重置为Unchanged)绝对不会影响国有企业储存的国家。

http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/557e6db0-51df-45e5-a2e9-c31995969554

希望这有助于

+0

@Bobby谢谢,我看过同一篇文章迭戈当我昨天正在研究。但他表示:“只有在以下情况下,STEs才会进入自我跟踪模式:a。它们被反序列化到客户端中......”这对我而言意味着当对象从我的WCF服务中拉出并反序列化到客户端时,它应该开始跟踪模式。这应该将其置于UnModified状态。我没有看到使用STE的好处,如果它不为我做。它只是提供了一些额外的状态跟踪(它并不适用于无状态环境:) – Jay 2010-01-22 17:36:44

0

我不认为我曾经说,国营贸易公司还没有准备好真实的世界。他们不会适合每个人。对于那些只需要能够轻松工作的数据集/数据表用户而言,它们是一款相当不错的工具。对于这些用户(他们中有很多人)将STE实体放入客户端应用程序中并不是什么坏事。这可能已经拥有了管道的两面。

+0

嘿,朱莉,欢迎来到Stack Overflow。我发现你的书是非常有用的,即使它不包含EF 4(STE等),它仍然适用于所有EF概念。 – 2010-02-28 10:50:25

+0

那么,当简单的解决方案到位时,为什么我们会以困难的方式做事。 – ashraf 2010-03-23 19:59:01

1

我对此的观察是,虽然EF4中的STE在客户端为有状态的情况下运行良好,但在无状态环境中,它们无法按预期工作。

MVC强调了这个缺点。例如,让我们看一个典型的实体“用户”和一个典型的场景,EditController和Edit视图。当我们访问我们的数据库(获取用户,开始跟踪,返回)或我们的服务(反序列化后自动启用更改跟踪)时,实体在控制器和视图内按预期行为。

但是,当邮政回来时,我们的Controller方法得到的实体是一个新的实体而不是在Get请求上给予我们的实体。所以这个实体没有变化跟踪,处于Added状态,并且如果我们将它作为在Get阶段交给我们的同一个实例处理,我们的数据库就会大打折扣。

当前,您可以将EF4 STE标记为已修改,应用更改并在实体真正新增或标记为“添加”时进行保存。这就是你现在可以做的所有事情来支持这种情况。除非MVC团队提出更好的模式来支持STE,或者除非在实例化模型以缓存实体实例时更改模型联编程序的默认行为......