3

我有一个 MVC2 应用程序,我开始使用STE的。我正在寻找有关更新应该如何工作的一些说明。

背景:

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

然后我尝试调用Applychanges()SaveChanges()在此博客实体上执行更新,但由于与帖子的 FK 关系以及数据库中有相关帖子但未附加到我发回的实体这一事实而失败。

通过一些进一步的测试......如果我在连接到服务器(状态=未更改)时获取博客实体的当前实例(以及所有相关的 FK 实体),则修改属性(状态=已修改)并更新它按预期工作.

所以我的问题是: 如果我的相关实体没有在视图中呈现,因此没有与 Blog 实体一起回发,更新应该工作吗?

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

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

4

4 回答 4

1

至于你的第一个问题:

然后我尝试在此博客实体上调用 Applychanges() 和 SaveChanges() 以执行更新,但由于与帖子的 FK 关系以及数据库中有相关帖子但未附加到我的实体这一事实而失败送回去。

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

至于你的第二个问题:

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

要考虑的问题是“您是否在服务器和客户端上使用相同类型的生成代码”?众所周知,当您使用数据服务元数据生成类型时,STE不会跟踪更改。对于 STE,有一段重要的代码在构造函数中被激活,它不会通过元数据生成的类型持续存在,因此是导致此问题的原因。

至于你的最后一个问题:

我应该能够直接从客户端和 ApplyChanges()/SaveChanges() 传递实体,还是应该将实体发回服务器,从数据库中获取现有副本,对该副本应用更改,然后发布现有的反对回来?

是的,有可能(我已经测试过)将 ApplyChanges()/SaveChanges() 应用于直接来自客户端的实体,而不管实体最初来自何处(从服务器作为新的在客户端被修改或创建)要添加的实体)。

于 2010-02-28T11:16:27.280 回答
1

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

MVC 突出了这个缺点。例如,让我们以一个典型的实体“用户”和一个典型的场景、EditController 和 Edit 视图为例。

当我们访问我们的数据库(获取用户、开始跟踪、返回)或我们的服务(反序列化后更改跟踪自动打开)时,实体在控制器和视图中的行为与预期一致。

但是,当 Post 返回时,我们的 Controller 方法获取的实体是一个新实体,而不是在 Get 请求中提供给我们的实体。因此,该实体没有更改跟踪,处于已添加状态,如果我们将其视为在获取阶段传递给我们的同一实例,它将炸毁我们的数据库。

目前,您可以将 EF4 STE 标记为已修改、应用更改并在实体是真正新的或只是错误地标记为已添加时保存。这就是您现在可以做的所有事情来支持这种情况。除非 MVC 团队提出更好的模式来支持 STE,或者除非您在实例化模型以缓存实体实例时更改模型绑定器的默认行为......

于 2010-04-05T15:16:01.400 回答
0

我们在非常相似的问题上苦苦挣扎——围绕更新。根据我们收集到的信息,STE 尚未准备好投入生产,但确实考虑使用它们。

无论如何,这里的问题集中在附加和分离之间的区别,以及 ObjectStateManager 和 STE 之间的交互。在你描述的示例中,它确实有效,它之所以有效,是因为它一直是附加的,而 STE 从未真正转换到使用它的 STE 行为(这只发生在被反序列化到客户端之后,或者它们被重新附加到附加的实体上)。

回答为什么它们显示为已添加:

例如,当 STE 被实例化时,更改跟踪被停用,更改跟踪器中的默认状态为已添加。

我觉得这一切都令人困惑,对 Julia Lerman 的采访以及在线帖子似乎表明当前的 STE 版本还没有为现实世界做好准备......

请参阅 Diego Vega(EF 团队)的回复

当您在此模式下使用 STE 时,它们的行为大致与普通 POCO 对象一样。例如,您可以直接操作图表或使用 ObjectContext 和 ObjectStateManager 中的 API,并且您必须在调用 SaveChanges 之前调用 DetectChanges 以确保状态管理器在任何时候与图表同步。

最重要的是,标准对象服务 API 不知道 STE,因此,诸如 AcceptAllChanges 之类的方法(在您的示例中,在 SaveChanges 期间隐式调用该方法,并将投诉对象的 ObjectStateManager 状态重置为 Unchanged)绝对没有影响关于 STE 存储的状态。

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

希望这可以帮助

于 2010-01-22T17:11:37.470 回答
0

我不相信我曾经说过 STE 还没有为现实世界做好准备。他们只是不适合所有人。对于只想要一些可以轻松工作的数据集/数据表用户来说,它们是一个非常好的工具。对于这些用户(其中​​有很多用户)将 STE 实体放在客户端应用程序中并不是一件坏事。他们可能已经拥有管道的两侧。

于 2010-02-10T14:12:24.553 回答