保存EF4 POCO对象的变化时更新关系

 2023-02-17    436  

问题描述

实体框架4,POCO对象和ASP.NET MVC2.我有很多关系,让我们在Blogpost和标签实体之间说.这意味着在我的T4生成的Poco Blogpost类中我有:

public virtual ICollection<Tag> Tags {
    // getter and setter with the magic FixupCollection
}
private ICollection<Tag> _tags;

我要求从objectContext的实例寻求博客和相关标签,并将其发送到另一层(在MVC应用程序中查看).稍后我通过更改的属性并更改了更改的关系来返回更新的博客.例如,它标记了”A””B”和”C”,新标签是”C”和”D”.在我的特定示例中,没有新的标签,标签的属性永远不会改变,因此唯一应该保存的是更改的关系.现在我需要在另一个ObjectContext中保存此内容. (更新:现在我尝试在同一上下文实例中执行,也失败.)

保存EF4 POCO对象的变化时更新关系

问题:我无法正确地保存关系.我尝试了我发现的一切:

  • controller.updateModel和controller.TryupDateModel不起作用.
  • 从上下文中获取旧博客,然后修改集合不起作用. (来自下一个点的不同方法)
  • 这个可能会起作用,但我希望这只是一个解决方法,而不是解决方法:(.
  • 在各种可能的组合中尝试用于博客普斯特和/或标签的博客和/或标签的函数.失败.
  • 这个看起来像我需要,但它不起作用(我试图解决它,但不能为我的问题).
  • 尝试了changestate/add/附加/…上下文的关系对象.失败.

“不起作用”在大多数情况下,我在给定的”解决方案”上,直到它不会产生任何错误并至少节省Blogpost的属性.与关系发生的情况有所不同:通常标记再次添加到标签表中,并使用新的PKS和保存的博客引用那些而不是原始的博客.当然,返回的标签有pks,在保存/更新方法之前,我检查pks,它们等于数据库中的pks,所以可能ef认为它们是新的对象,那些pks是临时的.

一个问题,我知道的问题,可能会发现一个自动化的简单解决方案:当更改Poco对象的集合时,应该由上面提到的虚拟集合属性发生,因为修复程序技巧将更新反向引用另一端是多对多的关系.但是,当查看”返回”更新的Blogpost对象时,那不发生.这意味着可能对我的问题没有简单的解决方案,但这会让我非常悲伤,我会讨厌ef4-poco-mvc胜利:(.也意味着EF不能在MVC环境中做到这一点使用EF4对象类型:(.我认为基于快照的更改跟踪应该找出已更改的Blogpost具有与现有PKS标记的关系.

btw:我认为与一对多关系发生同样的问题(谷歌和我的同事这么说).我会在家里试一试,但即使这是在我的应用中的六个多对多的关系中没有帮助我的作品:(.

推荐答案

让我们这样尝试:

  • 将blogpost附加到上下文.将对象附加到上下文上下文对象的状态,所有相关对象和所有关系都设置为不变.
  • 使用context.ObjectStateManager.changeObjectState将Blogpost设置为修改的
  • 迭代标签集合
  • 使用context.ObjectStateManager.changerelationShipState在当前标记和博客之间的关系设置状态.
  • Savechanges

编辑:

我猜我的一个评论给了你假希望EF将对您进行合并.我扮演了很多问题,我的结论说,EF不会为你做这件事.我认为你还发现了我的问题 msdn .实际上,互联网上有很多这样的问题.问题是,它没有明确说明如何处理这种情况.所以让我们看看问题:

问题背景

EF需要跟踪实体的更改,以便持久性知道必须更新,插入或删除哪些记录.问题是,它是objectContext责任跟踪更改. ObjectContext能够跟踪仅适用于附加实体的更改.在ObjectContext之外创建的实体根本不会跟踪.

问题描述

基于以上描述,我们可以清楚地说明EF更适合于连接方案,其中实体始终附加到上下文 – 典型的WinForm应用程序. Web应用程序需要断开连接的方案,其中在请求处理和实体内容被传递给客户端时,将上下文关闭.下一个HTTP请求提供了必须重新创建的实体的修改内容,附加到新上下文并持久.娱乐通常会发生在上下文范围之外(具有持久性Ignorace的分层架构).

解决方案

所以如何处理这种断开的方案?使用POCO类时,我们有3种方法来处理更改跟踪:

  • 快照 – 需要相同的上下文=无用于断开连接场景
  • 动态跟踪代理 – 需要相同的上下文=无用于断开连接场景
  • 手动同步.

单个实体上的手动同步是简单的任务.您只需要附加实体并调用AddObject for插入,deleedObject用于删除或在objectStateManager中删除或设置状态以修改以修改以进行更新.当您必须处理对象图而不是单个实体时,真正的疼痛就会来.当您必须处理独立协会(那些不使用外国关键财产的人)和许多关系时,这种疼痛甚至更糟糕.在这种情况下,您必须手动同步对象图中的每个实体,而且在对象图中的每个关系中也是如此.

手动同步是由MSDN文档的解决方案:附加和分离对象说:

对象附加到对象
上下文处于不变状态.如果你
需要更改对象的状态
或者关系因为你知道
您的对象已被修改
独立状态,使用其中一个
以下方法.

所提到的方法是ChangeObjectState和changerelationShipState的ObjectStateManager =手动更改跟踪.类似的提议是在其他MSDN文档文档中:定义和管理关系说:

如果您正在使用断开连接
您必须手动管理的对象
同步.

此外,

还有博客文章与EF v1相关,这批评了EF的完全这种行为.

解决方案的原因

EF有许多”有用”的操作和设置,如 refresh , load , applycurrentvalues , applyoriginalvalues , mergeOption 等.但是,通过我的调查,所有这些功能仅适用于单个实体,并仅影响Scalar Preperties(=不是导航属性和关系).我宁愿不测试这些方法,其中包含嵌套在实体中的复杂类型.

其他提出的解决方案

而不是真正的合并功能,EF团队提供了一个名为自我跟踪实体(ste),它不解决问题.首先,所有STE仅适用于同一实例用于整个处理.在Web应用程序中,除非您在视图状态或会话中存储实例,否则不是这种情况.由于我非常不满意,使用EF,我将要检查nhibernate的功能.第一次观察说,Nibernate可能有这样的 functions .

结论

我将通过单链接到另一个

原文链接:https://77isp.com/post/34174.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。