• 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并深入探讨。

  • 相关阅读:
    spring boot 配置时区差别
    Java 中序列化与反序列化引发的思考?
    Http 状态码总结
    Springboot
    ConcurrentHashMap 实现缓存类
    C#基础(二)拆箱与装箱,循环与选择结构,枚举
    C#基础知识(一)自己总结的。。。
    贪吃蛇大作战双人版加强版完整代码加详细步骤,不懂问博主 啦啦啦。
    C#数组随机生成四个随机数
    C#添加背景音乐
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/9175636.html
Copyright © 2020-2023  润新知