如何在EntitySpaces中添加延迟加载的列?

时间:2016-04-27 08:18:29

标签: orm entityspaces

如果您没有经验或目前没有使用EntitySpaces(" ES")ORM,则此问题不适合您。

我有一个10岁的申请,4年后现在需要我的注意。我的应用程序使用了一个名为EntitySpaces的现已解散的ORM,我希望如果您正在阅读本文,您有经验或者仍然可以使用它!此时切换到另一个ORM不是一个选项,所以我需要找到一种方法来使这项工作。

在我上次积极处理我的应用程序和现在(ES版本2012-09-30)之间,EntitySpaces(" ES")已经在底层ADO.net中经历了重大变化 - 结束。我寻求帮助的场景是实体集合只加载了一部分列:

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

然后我覆盖在初始选择中未加载的属性,以便我可以在访问器中延迟它们。以下是一个这样的懒惰加载属性的示例,它曾经完美地工作。

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[]));

当我更新到当前(和开源)版本的ES(版本2012-09-30)时,我不得不注释掉该访问者的所有ADO.net相关内容。这意味着" ImageData"列未正确配置,当我更改它的数据并尝试保存实体时,我收到以下错误:

  

专栏' ImageData'不属于桌子。

我花了几天时间浏览ES资源并进行实验,看起来他们不再使用DataTable来支持实体,而是使用了“esSmartDictionary”#。

我的问题是:是否有一种已知的,受支持的方式来完成以前在新版ES中工作的延迟加载行为?我可以通过告诉ORM将其添加到实体后备存储中来更新未包含在初始选择中的属性(即列)吗?

1 个答案:

答案 0 :(得分: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感兴趣。如果我认为它有未来,我会很乐意继续努力,但事实并非如此。 :(

我仍然对其他用户的任何其他方法或见解感兴趣。