Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework upgrade to 6.2.0 from 6.1.x breaks certain queries unless I enable MARS

Tags:

I recently upgraded EF 6.1.3 to 6.2.0 on one of our large projects, and it has broken a significant amount of our LINQ queries. Enabling MultipleActiveResultSets causes everything to work as normal again, but I'm struggling to understand the change. We have been using EF for years and gone through multiple major version changes without any issue. If I simply revert back to 6.1.3, everything works again as expected - in fact everything works even if I explicitly disable MARS in 6.1.3.

Let me give a few simplified examples. The first problem is with 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 in 6.2.0 throws a "There is already an open DataReader..." exception. I understand the nature of the exception, and I can solve this by calling ToList() on the outer query to push the results into memory first - what I don't understand is why I didn't have to do this in 6.1.3 (even with MARS disabled). It isn't always desirable to simply load the whole outer set into memory.

This also seems to impact lazy-loaded properties. For example, we build ComboBoxes from simple queries like this:

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 throws the "There is already an open DataReader..." exception. The fix is I now have to eager-load the navigation property.

Ultimately I don't have an explicit question, I'm just trying to understand why a minor version update seemingly caused major breaking changes in how queries are handled.

Moving forward, this impacts far too many queries for us to refactor. When I was researching the problem, I saw vague warnings about enabling MARS, but nobody really gave anything concrete. Is there a compelling reason not to enable it?

like image 459
amnesia Avatar asked Nov 09 '17 17:11

amnesia


People also ask

How do I update entity framework?

Right-click on your project and select Manage NuGet Packages... If a previous version of the EntityFramework NuGet package was installed this will upgrade it to EF6.

What is difference between Entity Framework 5 and 6?

EF5 is built into the core of . NET 4.5, whereas EF6 has been shifted out, and is open source. This means that you must add the new EF6 assemblies to all of the relevant projects in the solution, in particular the entry project. This means that you must remove assembly System.

Is Entity Framework 6 still supported?

Versions 6.0, 6.1, 6.2, and 6.3 are no longer supported. Although Entity Framework 6. x is still supported, it is no longer being developed and will only receive fixes for security issues.


1 Answers

you get this error because you're iterating through a result set while trying to open another result set (while the first one did not finish yet)-> sort of lazy loading (the first 'for each' iteration in your case) -> there are a lot of ways to solve this as you've already seen for yourself: using toList (drop to memory first), because it's no longer using the datareader to open the set.

it looks like it MIGHT be related to a bug fix in 6.2 (release notes: https://entityframework.net/ef-version-history) - looks like related to: "Bug: Retrying queries or SQL commands fails with "The SqlParameter is already contained by another SqlParameterCollection.")

Regarding enabling MARS: you can find special warning here:

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

like image 83
Yulian Avatar answered Sep 19 '22 09:09

Yulian