EntityFramework 6.x和EntityFramework Core必须需要MultipleActiveResultSets?

前言

本节我们来探讨到底需不需要在连接字符串上加上MultipleActiveResultSets = true ?,若您有更深层次的理解欢迎留下您的脚印。

EntityFramework 6.x和EntityFramework Core需要MultipleActiveResultSets?

很多童鞋遇到如下图中错误就立马想到在连接字符串上加上 MultipleActiveResultSets = true ,但是这样真的是最终解决方案么?

下面我们来看一段在EntityFramework 6.x中的代码,演示如上问题的出现。

复制代码
            using (var ctx = new EfDbContext())
            {
                ctx.Database.Log = Console.WriteLine;

                var customers = ctx.Customers;

                foreach (var customer in customers)
                {
                    ctx.Entry(customer).Collection(d => d.Orders).Load();
                }
            };
复制代码

当您在EntityFramework 6.x中运行上述代码就会抛出如上图异常(不要关心上述代码是否合理,或许您可能说直接使用显式加载对吧,如上代码旨在引出问题)。然后我们在连接字符串上如下加上一句就可以解决问题。

connectionString="Data Source=WANGPENG;Initial Catalog=EntityFramework6;Integrated Security=true;MultipleActiveResultSets=True;"

我们知道MultipleActiveResultSets即MARS在SQL Server2005中被引入,意为单连接多请求,但是它非线程安全,在我看来这个特性在ADO.NET中可能非常适用,但是在EntityFramework 6.x中作用不大,虽然如上可以从数据库连接层面来解决问题,大部分这种情况的出现还是因为代码写的有问题,我们直接调用ToList即可,如下:

复制代码
            using (var ctx = new EfDbContext())
            {
                ctx.Database.Log = Console.WriteLine;

                var customers = ctx.Customers.ToList();

                foreach (var customer in customers)
                {
                    ctx.Entry(customer).Collection(d => d.Orders).Load();
                }
            };
复制代码

我们知道ToList是最终翻译成SQL语句请求数据库返回对应数据,即通过ToList既可以打开连接也可以关闭连接,当我们不用ToList时,此时打开了一个连接,同时已经有了一个DataReader,接下来遍历时则再会在Command上打开一个DataReader加载Orders,此时就会抛出第一个DataReader未关闭的情况,大部分出现这样的一样我们都可以通过ToList来解决,当然也可以用延迟加载(关于EF 6.x中延迟加载请谨慎适用,我在我的书中《你必须掌握的EntityFramework 6.x与Core 2.0》中也有讲到,除非您明确自己会正确使用)和显式加载来解决。那在EntityFramework Core中是否运行上述同样代码会抛出异常,然后我们需要在连接字符串上加上此特性呢?我们来看看。

            using (var context = new EFCoreDbContext())
            {
                var blogs = context.Blogs;
                foreach (var blog in blogs)
                {
                    context.Entry(blog).Collection(p => p.Posts).Load();
                }
            }

通过如上图我们知道完全不会如EntityFramework 6.x中抛出异常,这点有所不同。大部分情况下,出现如上异常或许可能是代码写的问题,不一定非得要加上 MultipleActiveResultSets=True;

总结

本文没有深入探讨文章标题,若您有抛出如上异常非得加上MultipleActiveResultSets=True才能解决问题,请留下您的评论,让我继续深入学习,在此表示感谢。接下来我会继续探讨和对比EntityFramework 6.x和EntityFramework Core中不为人知的秘密,同时也会陆续更新EF Core 2.1并深入探讨。


为了方便大家在移动端也能看到我分享的博文,现已注册个人公众号,扫描上方左边二维码即可,欢迎大家关注,有时间会及时分享相关技术博文。

感谢花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让楼主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/CreateMyself)/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   Jeffcky  阅读(1959)  评论(4编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示