EF4 和使用 AddObject 意外加载相关集合
我有一个奇怪的情况,添加记录会导致相关集合的不必要加载。
例如,我有请求和会话。一个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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我猜您正在使用 POCO T4 模板,它怀疑这种行为。问题是 POCO 模板生成的修复方法。每次您分配导航属性、外键或将对象添加到相关对象集合时,这些方法都会执行对象图修复。这意味着他们也会更新相关实体的导航。在您的场景中,这意味着修复方法将
Request
添加到Session
中的Requests
集合。访问集合会触发延迟加载。避免这种情况的唯一方法是:context.ContextOptions.LazyLoadingEnabled = false
)Session
中删除Requests
属性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
toRequests
collection in theSession
. Access to the collection will trigger lazy loading. The only ways to avoid this are:context.ContextOptions.LazyLoadingEnabled = false
)Requests
property fromSession
Requests
property (Session
will not support lazy loading)