NetCore 关于 IQueryable 的两道面试题【60%的C#程序员未必回答的上来】

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

面试场景是给你几道题,问你以下程序能不能正确执行

题目1

 IQueryable 用什么方式进行数据加载?DataTable 方式 还是 DataReader方式?

答案:

Ado.NEt中,DataTable、DataSet等是一次性将查询的数据加载到内存中,而DataReader属于按需加载。

IQueryable 采用的是DataReader方式读取数据,该方式并不会把查询的所有数据加载到内存中,而是根据处理速度进行按需加载。因此:它的优点是效率高,占用内存少。缺点是占用数据库链接时间长。

因此,在数据处理比较耗时的操作中,不建议使用DataReader,因此这样会占用数据库链接资源时间长。

题目2

        static void Main(string[] args)
        {
            using (wechatDbContext context=new wechatDbContext())
            {
                var org = context.OrgUints.Where(A => A.Parent == null).FirstOrDefault(); 
                Console.WriteLine(new String('.', 1) + org.OrgName);
                Print(10, context, org);
            } 
            Console.Read();
        } 

        static void Print(int Printlevel, wechatDbContext  context,OrgUint org)
        {
            var childs = context.OrgUints.Where(A => A.Parent == org);
            foreach(var item in childs)
            {
                Console.WriteLine(new String('.', Printlevel) + item.OrgName);
                Print(Printlevel*2, context, item);
            }
        }

 

 已经开启了一个DataReader,在开启新的DataReader之前必须先关闭已经开启的DataReader 

解释:

无论是SqlServer 数据库,还是MySql数据库,在使用DataReader时都不允许同时使用两个及以上的DataReader。

解决方法1:

  var childs = context.OrgUints.Where(A => A.Parent == org);

改成
  var childs = context.OrgUints.Where(A => A.Parent == org).ToList();

解决方法2:

如果您用的是SqlServer数据库【其他数据库此方式不行】,可以在链接字符串上增加如下内容:

MultipleActiveResultSets=true   显式声明允许两个及以上的dataReader同时运行
Data Source=LAPTOP-84R6S0FB;Initial Catalog=demo1;Integrated Security=True

改成

Data Source=LAPTOP-84R6S0FB;Initial Catalog=demo1;Integrated Security=True;MultipleActiveResultSets=true

题目3

        static void Main(string[] args)
        {
            var org = GetOrgUints();
            foreach(var item in org)
            {
                Console.WriteLine(item.OrgName);
            }
            Console.Read();
        }

        static IQueryable<OrgUint> GetOrgUints()
        {
            using (wechatDbContext context = new wechatDbContext())
            {
                var org = context.OrgUints.Where(A => A.Parent == null);
                return org;
            }
        }

 

 不能访问一个已经释放的数据库上下文

解释:

context.OrgUints.Where() 是一个IQueryable类型,IQueryable并不会立马去数据库执行,而context.OrgUints.Where() 在Using()内部,当离开Using()作用范围后,数据库上下文会释放,而foreach(var item in Org) 时会执行context.OrgUints.Where()的查询操作,因此:会抛出上述异常。

解决方法

var org = context.OrgUints.Where(A => A.Parent == null);
改成
var org = context.OrgUints.Where(A => A.Parent == null).ToList();

如有错误,请指出,谢谢~_~

@天才卧龙的拨客人

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章