2016-04-27 31 views
0

如果您沒有使用EntitySpaces(「ES」)ORM的經驗或目前沒有使用該問題,則此問題不適合您。如何在EntitySpaces中添加惰性加載列?

我有一個10年的應用程序,4年後,現在需要我的關注。我的應用程序使用了一個名爲EntitySpaces的現已不存在的ORM,並且我希望如果您正在閱讀這篇文章,您有經驗或者仍然可以使用它!切換到另一個ORM目前不是一種選擇,所以我需要找到一種方法來完成這項工作。

在我最後一次積極處理我的應用程序和現在(ES版本2012-09-30)之間,EntitySpaces(「ES」)經歷了底層ADO.net後端的重大變化。我正在尋求幫助的場景是當實體集合裝有僅列的子集:

_products = new ProductCollection(); 
_products.Query.SelectAllExcept(_products.Query.ImageData); 
_products.LoadAll(); 

我然後覆蓋那些沒有在最初選擇加載,這樣我可以lazyload屬性他們在訪問者中。這是一個這樣的懶惰加載屬性的例子,曾經完美地工作。

public override byte[] ImageData 
{ 
    get 
    { 
     bool rowIsDirty = base.es.RowState != DataRowState.Unchanged; 

     // Check if we have loaded the blob data 
     if(base.Row.Table != null && base.Row.Table.Columns.Contains(ProductMetadata.ColumnNames.ImageData) == false) 
     { 
      // add the column before we can save data to the entity 
      this.Row.Table.Columns.Add(ProductMetadata.ColumnNames.ImageData, typeof(byte[])); 
     } 

     if(base.Row[ProductMetadata.ColumnNames.ImageData] is System.DBNull) 
     { 
      // Need to load the data 
      Product product = new Product(); 
      product.Query.Select(product.Query.ImageData).Where(product.Query.ProductID == base.ProductID); 
      if(product.Query.Load()) 
      { 
       if (product.Row[ProductMetadata.ColumnNames.ImageData] is System.DBNull == false) 
       { 
        base.ImageData = product.ImageData; 

        if (rowIsDirty == false) 
        { 
         base.AcceptChanges(); 
        } 
       } 
      } 
     } 

     return base.ImageData; 
    } 
    set 
    { 
     base.ImageData = value; 
    } 
} 

有趣的部分就是我的列添加到基礎DataTable的DataColumn集合:

this.Row.Table.Columns.Add(ProductMetadata.ColumnNames.ImageData, typeof(byte[])); 

我不得不從訪問註釋掉所有ADO.net相關的東西,當我更新到目前(和開源)版本的ES(版本2012-09-30)。這意味着,「的ImageData」列配置不正確,當我改變它的數據,並試圖挽救我收到以下錯誤實體:

Column 'ImageData' does not belong to table .

我花了幾天翻翻ES源並進行實驗,看起來他們不再使用DataTable來支持實體,而是使用'esSmartDictionary'。

我的問題是:是否有一種已知的,支持的方式來完成過去在ES新版本中工作的相同的延遲加載行爲?在哪裏可以通過告訴ORM將其添加到實體支持存儲中來更新未包含在初始選擇中的屬性(即列)?

回答

0

在分析了ES如何構建用於更新的DataTable之後,很明顯未包括在初始選擇(即加載)操作中的列需要被添加到esEntityCollectionBase.SelectedColumns字典中。我添加了以下方法來處理這個問題。

/// <summary> 
/// Appends the specified column to the SelectedColumns dictionary. The selected columns collection is 
/// important as it serves as the basis for DataTable creation when updating an entity collection. If you've 
/// lazy loaded a column (i.e. it wasn't included in the initial select) it will not be automatically 
/// included in the selected columns collection. If you want to update the collection including the lazy 
/// loaded column you need to use this method to add the column to the Select Columns list. 
/// </summary> 
/// <param name="columnName">The lazy loaded column name. Note: Use the {yourentityname}Metadata.ColumnNames 
/// class to access the column names.</param> 
public void AddLazyLoadedColumn(string columnName) 
{ 
    if(this.selectedColumns == null) 
    { 
     throw new Exception(
      "You can only append a lazy-loaded Column to a partially selected entity collection"); 
    } 

    if (this.selectedColumns.ContainsKey(columnName)) 
    { 
     return; 
    } 
    else 
    { 
     // Using the count because I can't determine what the value is supposed to be or how it's used. From 
     // I can tell it's just the number of the column as it was selected: if 8 colums were selected the 
     // value would be 1 through 8 - ?? 
     int columnValue = selectedColumns.Count; 
     this.selectedColumns.Add(columnName, columnValue); 
    } 
} 

您可以使用此方法是這樣的:

public override System.Byte[] ImageData 
{ 
    get 
    { 
     var collection = this.GetCollection(); 
     if(collection != null) 
     { 
      collection.AddLazyLoadedColumn(ProductMetadata.ColumnNames.ImageData); 
     } 
... 

這是一個恥辱,沒有人感興趣的開源EntitySpaces。如果我認爲它有未來,我很樂意爲此工作,但事實並非如此。 :(

我仍然對其他用戶的任何其他方法或洞察力感興趣