Updating the Entity Framework to 6.2.0 from 6.1.x interrupts certain requests if I do not enable MARS

I recently upgraded EF 6.1.3 to 6.2.0 on one of our major projects, and it violated a significant amount of our LINQ queries. Enabling MultipleActiveResultSets makes everything work fine, but I'm struggling to understand the changes. We have been using EF for many years and without any problems have gone through several major changes. If I just go back to 6.1.3, everything will work just as expected - in fact, everything works, even if I explicitly disable MARS in 6.1.3.

Let me give you some simplified examples. The first problem is related to nested queries:

foreach(var row in dbSet.Where(<condition>)) foreach(var innerRow in otherDbSet.Where(_ => _.Property == row.Property)) 

This works fine in 6.1.3, but an exception is thrown in 6.2.0 "There is already an open DataReader ...". I understand the nature of the exception, and I can solve this by calling ToList () in an external query to first transfer the results to memory - I don't understand why I shouldn't have done this in 6.1.3 (even with MARS disabled). It is not always advisable to simply load the entire external set into memory.

It also looks like lazy properties. For example, we create ComboBoxes from simple queries, such as:

 return db.Collection .Where(<condition>) .AsEnumerable() .Select(_ => new ListItem(_.Id, _.LazyNavigationProperty.Description)) .ToList(); 

This works fine in 6.1.3, but again, in 6.2.0, the exception "There is already an open DataReader ..." is thrown. Bugfix - now I need to look forward to loading the navigation property.

Ultimately, I donโ€™t have an explicit question, I'm just trying to understand why a minor version update seems to have caused a serious violation of changes in request processing.

Moving forward, this affects too many requests for refactoring. When I studied the problem, I saw vague warnings about the possibility of MARS, but no one gave anything concrete. Is there any good reason not to include it?

+18
source share
2 answers

You get this error because you iterate over the result set, trying to open another result set (until the first one has finished) โ†’ some kind of delayed loading (the first โ€œfor eachโ€ iteration in your case) โ†’ There are many ways to solve this problem, how do you Youโ€™ve already seen for yourself: use toList (first transfer to memory), because it no longer uses a data reader to open the set.

it looks like it MAY be related to fixing the bug in 6.2 (release notes: https://entityframework.net/ef-version-history ) - it seems to be related to: "Error: retries of queries or SQL commands fail using "The SqlParameter" is already contained in another SqlParameterCollection. ")

Regarding the inclusion of MARS: you can find a special warning here:

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets

0
source

Entity Framework should provide a tiny abstraction of your database model.

Such work requires several queries to be performed under the hood. The engine may also require more requests than the same manual encoded workload.

This is a physiological evolution that allows you to handle all possible user requests. A simple upgrade to a different version of the Entity Framework can lead to differences in the database workload created by the internal hardware.

MARS is required because EF has changed the way it searches for an object (in particular, inside loops combined with deferred loading). Unfortunately, in most cases you need to use MARS when using the Entity Framework.

Currently, using async/await usually requires MARS .

0
source

Source: https://habr.com/ru/post/1273245/


All Articles