0

私は telerik の OpenAccess ORM を使用しており、生成されたコードにいくつかの変更を加えています。ナビゲーション プロパティ (別のテーブルへのキー) を持つエンティティの場合、これらは次のような IList として生成されます。

private IList<SystemUser> _SystemUsers = new List<SystemUser>();
public virtual IList<SystemUser> SystemUsers 
{ 
    get
    {
        return this._SystemUsers;
    }
}

SystemUsersまず、データベースに対して実際にクエリが行われるのはどの時点でしょうか? これは IList であるため、オブジェクトの作成時にデータベースに対して実行されると考えていましたが、そうではないことはわかっています。

私がやりたいことは、生成されたすべてのナビゲーション プロパティで削除されたアイテムを除外することであり、次のコードでこれを行うために t4 テンプレートに変更を加えています。

private IList<SystemUser> _SystemUsers = new List<SystemUser>();

public virtual IList<SystemUser> SystemUsers 
{ 
    get
    {
        if (!Entities.IncludeDeletedEntities)
        {
            var currentContext = Entities.GetContext(this);
            ContextChanges changes = currentContext.GetChanges();
            IList<SystemUser> deletedItems = changes.GetDeletes<SystemUser>();
            return this._SystemUsers.Except(deletedItems).ToList(); //Question is here
        }

        return this._SystemUsers;
    }
}

基本的に、これはコレクションから削除対象としてマークされたコレクションを差し引いたものを返すだけです。私の懸念は、.ToList()それがいつ実行されるかです。ToList()にアクセスするたびにデータベースに対してクエリを実行することでクエリの速度を低下させたくはありませんがSystemUsers、アイテムをフィルター処理する必要もあります。ToList()それがデータベースヒットを引き起こすかどうかさえわかりません。コードが実際にデータベースにヒットする時期がわからないので、SystemUsersさらにフィルター (where 句、where 句、等)。

4

2 に答える 2

1

Telerik ツールについては確かなことは言えませんが、GetEnumerator (ToList によって内部的に呼び出される) への呼び出しで任意の式を評価する EF および LINQ to SQL に多少似ていると思われます。これを自分でテストするには、プロファイリング ツールを使用して、データベース リクエストが行われている場所を正確に特定します。プロファイリングには、SQL プロファイラーと Intellitrace が機能するはずです。他の商用プロファイラーも利用できますが、Telerik Open Access に何があるかはわかりません。彼らのフォーラムをチェックしたいかもしれません。

于 2013-03-12T13:21:34.737 に答える
0

OpenAccess についてはわかりませんが、エンティティ フレームワークとほぼ同じ原則が適用されると思います。その背景から、私はあなたのコードに大きな問題しか見ません。

最初の異議は、アーキテクチャの観点からのものです。エンティティ オブジェクトは、コンテキストの存在を認識していないはずです。

その他の異論は技術的なものです。

  • すでに指摘したように、コードは対処されるたびに実行されSystemUsersます。これToList()により、常にデータベース ヒットが発生します。を削除するとどうなるかわかりませんがToList()、それは何と何GetChangesをするかによって異なりGetDeletesます。知らない。しかし、少なくとも、SystemUsers列挙されるたびに追加のデータベース ヒットが発生します。

  • EF と同様に、OpenAccess も、 とマークされたコレクションの遅延読み込みをサポートしていると思いますvirtual。おそらく、エンティティ型から派生し、遅延読み込みを実装するためにナビゲーション プロパティに配線を追加するプロキシ型を作成します。プロパティには getter しかないので、OpenAccess はAdd項目をコレクションに取り込むことでコレクションを作成すると仮定します。これにより、あらゆる種類の副作用が発生します。

    1. これは、アイテムが追加されるたびにベース プロパティにアクセスする (クエリを実行する) ことを意味します。
    2. コードは一時リストを返します。追加されたアイテムは、次にプロパティに対処するときに消えます!! コレクションに値が入力されることはありません。
  • 最後に、オブジェクトの具体化中に 2 番目のリーダーが開かれると、予期しない動作が発生する可能性があります。

したがって、削除対象としてマークされたエンティティの有無にかかわらずエンティティを返すリポジトリによって、ソフト削除の問題を解決する必要があると思います。または、「削除された」ものを除いて SystemUsers を返す計算された (マップされていない) プロパティを作成することもできます。

于 2013-03-12T14:14:06.420 に答える