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();

如有錯誤,請指出,謝謝~_~

@天才臥龍的撥客人

 

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