EF4 和使用 AddObject 意外加载相关集合

发布于 2024-11-04 10:47:33 字数 1291 浏览 0 评论 0原文

我有一个奇怪的情况,添加记录会导致相关集合的不必要加载。

例如,我有请求和会话。一个Session可以包含多个Request。我已经加载了会话,只想添加一个新请求。

但是,当我在请求存储库的 ObjectSet 上设置 call AddObject 时,SQL Profiler 会显示对该会话上的所有相关请求执行的选择查询。

这是问题代码:

this._request = new Request
                    {
                        Action = (string)filterContext.RouteData.Values["action"],
                        Controller = filterContext.Controller.GetType().Name,
                        DateAdded = userContext.Session.DateLastActive,
                        IpAddress = filterContext.HttpContext.Request.UserHostAddress,
                        SessionId = userContext.Session.Id
                    };

loggingService.AddRequest(this._request);

最后一行仅调用我的服务,而该服务又仅调用 _objectSet.AddObject(entity)

如果我尝试设置新请求的 Session = userContext.Session (而不是上面的 SessionId = userContext.Session.Id),也会发生同样的事情 - 查询将执行在设置此属性时,而不是在 AddObject 上。因此,EF4 似乎认为,当出于某种原因引用会话时,它需要会话上的相关请求集合。

但我不需要会话上的关联请求,也不需要使用或引用这些请求。所以我不确定为什么 EF4 会加载它们。我单步执行了代码,并验证了这恰好发生在 AddObject(entity) 行上(Profiler 显示在同一实例中执行的查询)。

为什么会发生这种情况,我该如何阻止它?

提前致谢。

编辑:这是因为 EF4 试图将新请求添加到相关的 Session.Requests 集合中,并且也检索所有其他请求吗?如果是这样,有什么办法可以防止这种情况发生吗?就像我说的,我不需要这些请求,我只需要添加它并继续。

I have an odd case where adding a record is causing unwanted loading of a related collection.

For example, I have Requests and Sessions. A Session can contain many Requests. I already have loaded the session, and just want to add a new request.

However, when I set call AddObject on the ObjectSet of the Request repository, SQL Profiler shows a select query getting executed on all related requests on that session.

Here is the problem code:

this._request = new Request
                    {
                        Action = (string)filterContext.RouteData.Values["action"],
                        Controller = filterContext.Controller.GetType().Name,
                        DateAdded = userContext.Session.DateLastActive,
                        IpAddress = filterContext.HttpContext.Request.UserHostAddress,
                        SessionId = userContext.Session.Id
                    };

loggingService.AddRequest(this._request);

That last line just calls into my service, which in turn, just calls _objectSet.AddObject(entity).

The same thing would happen if I tried setting the new Request's Session = userContext.Session (instead of the above SessionId = userContext.Session.Id) -- the query would execute on setting this property, instead of on AddObject. So it's seems EF4 thinks it needs the related Request collection on the Session when it's referenced for some reason.

But I don't need the associated requests on the session, nor are the being used or referenced. So I'm not sure why EF4 is loading them. I stepped through the code, and verified that this happens exactly on the AddObject(entity) line (Profiler shows the query getting executed at the same instance).

Why would this happen, and how can I stop it?

Thanks in advance.

EDIT: Is this because EF4 is trying to add the new Request to the related Session.Requests collection, and goes and retrieves all of the other ones too? If so, is there any way to prevent that? Like I said, I don't need those Requests, I just need to add it and move on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帅气称霸 2024-11-11 10:47:33

我猜您正在使用 POCO T4 模板,它怀疑这种行为。问题是 POCO 模板生成的修复方法。每次您分配导航属性、外键或将对象添加到相关对象集合时,这些方法都会执行对象图修复。这意味着他们也会更新相关实体的导航。在您的场景中,这意味着修复方法将 Request 添加到 Session 中的 Requests 集合。访问集合会触发延迟加载。避免这种情况的唯一方法是:

  • 关闭此操作的延迟加载 (context.ContextOptions.LazyLoadingEnabled = false)
  • Session 中删除 Requests 属性
  • 修改 T4 模板并删除修复方法
  • 修改 T4 模板并从 Requests 属性中删除 virtual(Session 将不支持延迟加载)

I guess you are using POCO T4 template which suspects exactly this behavior. The problem are fixup methods generated by POCO template. Every time you assign navigation property, foreign key or add object to collection of related objects these methods performs object graph fixup. It means they update navigation on related entity as well. In your scenario it means that fixup methods adds Request to Requests collection in the Session. Access to the collection will trigger lazy loading. The only ways to avoid this are:

  • Turn off lazy loading for this operation (context.ContextOptions.LazyLoadingEnabled = false)
  • Remove Requests property from Session
  • Modify T4 template and remove fixup methods
  • Modify T4 template and remove virtual from Requests property (Session will not support lazy loading)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文