[Data Access] ORM 原理 (8-2) : 對延遲載入的物件進行資料載入

在原理 (8) 中,我們展示了物件集合的處理與延遲載入,但忘了提到一件事,當延遲載入的物件要載入資料時要怎麼做。不過它的作法沒有特別困難,只是要產生一個有條件的 SQL 指令,並將傳回的資料填到物件內即可。

在原理 (8) 中,我們展示了物件集合的處理與延遲載入,但忘了提到一件事,當延遲載入的物件要載入資料時要怎麼做。不過它的作法沒有特別困難,只是要產生一個有條件的 SQL 指令,並將傳回的資料填到物件內即可。

不過,對於單一物件和物件集合,作法會不太一樣,這是因為資料庫連線的開關使然,因為開啟和關閉連線也是需要時間的,可以省下這個時間的話對效能會有比較正面的影響,所以我們在單一物件中加入一個 Load 方法:

   1: public virtual void Load()
   2: {
   3:     Type thisType = this.GetType();
   4:  
   5:     if (thisType == typeof(EntityObject))
   6:         return;
   7:  
   8:     // load entity's all data from database with the lazy loading object.
   9:     DB.DataContext context = new DB.DataContext("sql");
  10:     MethodInfo methodGetEntity = context.GetType().GetMethod("GetEntity");
  11:     methodGetEntity = methodGetEntity.MakeGenericMethod(thisType);
  12:  
  13:     // invoke.
  14:     object result = Convert.ChangeType(methodGetEntity.Invoke(context, new object[] { this }), thisType);
  15:     PropertyInfo[] properties = result.GetType().GetProperties();
  16:  
  17:     foreach (PropertyInfo property in properties)
  18:     {
  19:         if (property.DeclaringType.BaseType != typeof(object))
  20:         {
  21:             PropertyInfo thisProperty = thisType.GetProperty(property.Name);
  22:  
  23:             if (thisProperty != null)
  24:                 thisProperty.SetValue(this, property.GetValue(result, null), null);
  25:         }
  26:     }
  27:  
  28:     this.Status = EntityStatus.Unchanged;
  29:     result = null;
  30:     context = null;
  31: }

 

而在 EntityCollectionObject<T> 中,也加入一個 Load 方法,只是它是共用同一連線的版本:

   1: public void Load()
   2: {
   3:     if (this.GetType().Name == "EntityCollectionObject")
   4:         return;
   5:  
   6:     DB.DataContext context = new DB.DataContext("sql");
   7:     context.EnableProviderBulkLoad();
   8:     context.Open();
   9:  
  10:     foreach (T item in this)
  11:     {
  12:         Type thisType = typeof(T);
  13:  
  14:         // load entity's all data from database with the lazy loading object.
  15:         MethodInfo methodGetEntity = context.GetType().GetMethod("GetEntity");
  16:         methodGetEntity = methodGetEntity.MakeGenericMethod(thisType);
  17:  
  18:         // invoke.
  19:         object result = Convert.ChangeType(methodGetEntity.Invoke(context, new object[] { item }), thisType);
  20:         PropertyInfo[] properties = result.GetType().GetProperties();
  21:  
  22:         foreach (PropertyInfo property in properties)
  23:         {
  24:             if (property.DeclaringType.BaseType != typeof(object))
  25:             {
  26:                 PropertyInfo thisProperty = thisType.GetProperty(property.Name);
  27:  
  28:                 if (thisProperty != null)
  29:                     thisProperty.SetValue(item, property.GetValue(result, null), null);
  30:             }
  31:         }
  32:  
  33:         typeof(T).GetProperty("Status").SetValue(item, EntityStatus.Unchanged, null);
  34:         result = null;
  35:     }
  36:  
  37:     context.Close();
  38:     context.DisableProviderBulkLoad();
  39:     context = null;
  40: }

 

有了這兩個方法後,我們就可以直接用物件本身或集合的 Load() 來載入完整的資料了。