Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF4 and undesired loading of related collection with AddObject

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.

like image 792
Jerad Rose Avatar asked May 02 '11 06:05

Jerad Rose


1 Answers

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)
like image 123
Ladislav Mrnka Avatar answered Oct 05 '22 06:10

Ladislav Mrnka