0

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 にエンティティ バッキング ストアに追加するように指示することで、最初の選択に含まれていなかったプロパティ (つまり、列) をどこで更新できますか?

4

1 に答える 1

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 に誰も興味を持っていないのは残念です。将来性があると思えば喜んで取り組みたいのですが、そうではないようです。:(

私はまだ他のアプローチや他のユーザーからの洞察に興味があります.

于 2016-04-27T21:35:31.320 に答える