3

私は、アセンブラーパターンを使用してLinqToEntityエンティティをサービスレベルでデータ転送オブジェクトにアセンブルし、それをクライアントレイヤーに渡して使用するプロジェクトに取り組んでいます。このアプローチは、エンティティオブジェクトを、サービス呼び出しに固有の情報を提供する単純化されたフラットなオブジェクトに変換することでした。

例えば。

// Original Entity looks something like this
public class PersonEntity
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int MotherId { get; set; }  
   public PersonEntity Mother { get; set; }
   // lots of other properties
}

// Flattened DTO
public class PersonSummaryInfo
{
  public int Id { get; set; }
  public string FullName { get; set; }
  public string MothersFullName { get; set; }
}

この例では、アセンブラーはPersonSummaryInfoを作成し、プロセスのFullNames部分を構築します。

サードパーティのコントロール(Telerik ASP.NET MVC GridControl)で問題が発生しました。このコントロールは、モデルのプロパティに基づいて(IQueryableを使用して)フィルター処理するように設定されています。単一層の設計があり、データベースエンティティをビューに直接送り込むという考えがあるようですが、これは我慢できません。

それを私のロジックに取り込もうとすると、GridControlはエンティティではなく私のDTOにバインドします。これは、何かをソートしようとするまではすべて有効です。私はすべてのIQueryableのものを非常に一般的な方法でサービスにプッシュし、これに責任を持つようにしました。並べ替えは、たとえばDTOでMothersFullNameを並べ替えようとします(その動作は、「MothersFullName」を文字列として並べ替えロジックに渡すことです)。これは、リフレクションを通じてエンティティを並べ替えようとし、IQueryableレイジーを利用する私のサービスにプッシュされます。読み込み中ですが、もちろんクエリが実行されると、「MothersFullName」は元のエンティティのプロパティではないため、例外がスローされます。

この種の実装を処理する優れた戦略はありますか?アプリケーションのサービスレイヤーに戻ったら、DTOをORMエンティティに効果的に「分解」するのは良い習慣ですか?または、オブジェクトが何であるか(FirstNameとLastNameを使用してフルネームを並べ替える方法など)についての知識が豊富な、よりリッチなオブジェクトを渡す方がよいでしょうか。

私の要件の鍵は次のとおりです。

  • 彼らはそれが好きなので、派手なTelerikコントロールを使用してください
  • サービスレベルでの遅延読み込みの結果(つまり、200万レコードを戻さず、10を表示するだけ)
  • フィルタリング、ページングなどをサポート
  • 健全なアーキテクチャの実装
4

3 に答える 3

4

あなたは自分の前にいくつかの選択肢があります。まず第一に、IQueryableにバインドできるのは事実です。これは、もちろん開発時間の観点から、IQueryableを実行するための最速の(そして最も一般的な)方法だからです。

あなたの場合(ORMの上にある本格的なサービスレイヤー)、状況は少し異なります。個人的には、少し掘り下げて、グリッドにカスタムバインディングを提供することをお勧めします。並べ替えとフィルタリングのためにクエリできるGridCommandオブジェクトを取得し、それを使用してサービスレイヤーにデータを要求します。これは、直面している問題を解決する簡単な方法について言及するのに適した場所です(これは、式がDTOプロパティに基づいているということです)。DynamicLinqを使用してみることができます。式から文字列クエリを作成し、それらをDALに渡すだけです。

実際のところ、これはTelerikの別の製品であるOpenAccessORMによって提案されたベストプラクティスです。OpenAccess SDKには、同様のアーキテクチャを使用するいくつかの例(特に、WCFプレーンサービスの例)が含まれています。この製品は、サービスレイヤー全体を提供するコード生成ツールも提供します。

于 2012-06-09T17:42:45.980 に答える
0

このソリューションで行きました。

グリッド固有の列を含むSQLビューを作成します。次に、データ転送オブジェクトがビューのプロパティと完全に一致するプロパティを使用するようにしました。これを達成するための最もクリーンで強力な方法ではありませんが、少なくとも、それを必要としないプロジェクトからデータ参照を取得します。

動的なlinqを使用せず、代わりに一般的なアプローチを維持し、リフレクションを使用して一致する列名を取得しました。すでにサービスレイヤー全体が実装されているという理由だけで、TelerikのOpen Accessには行きませんでしたが、それは素晴らしい解決策のように思えます。

それはすべてまだIQuery可能であるため、非常に効率的に機能します(GridViewがプロパティのプロパティであるGridViewModelsと一致することを確認するために開発者に依存するだけです)。

于 2012-07-13T16:07:07.343 に答える
0

すぐに使用できる並べ替え機能にのみRadGridを使用していますか?私はこれと同じ問題に遭遇し、RadListViewを使用してページャー/ソートを接続するだけで終わりました。テンプレートを使用すると、SortExpessionプロパティを使用して何を並べ替えるかを正確に指示できます。次に、適切なイベントを発生させます。これが私のイベントハンドラーです。手に入れて起動できるものなら何でも設定できます。これが解決策かどうかはわかりませんが、うまくいけば、解決策を見つけるのに役立ちます。

protected void SortSearchTickets(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
    {
        var selectedValue = e.Value;
        lsvSearchResults.SortExpressions.Clear();
        var sortExp = new RadListViewSortExpression();

        switch (selectedValue)
        {
            case "ID":
                sortExp.FieldName = "TicketID";
                break;
            case "TicketType":
                sortExp.FieldName = "TypeDescription";
                break;
            case "Subject":
                sortExp.FieldName = "Subject";
                break;
            case "Status":
                sortExp.FieldName = "Status.Key";
                break;
            case "DueDateDesc":
                sortExp.FieldName = "DueDate";
                sortExp.SortOrder = RadListViewSortOrder.Descending;
                break;
            case "DueDateAsc":
                sortExp.FieldName = "DueDate";
                sortExp.SortOrder = RadListViewSortOrder.Ascending;
                break;
            case "Assigned To":
                sortExp.FieldName = "AssignedTo.Key";
                break;
            case "Assigned By":
                sortExp.FieldName = "AssignedBy.Key";
                break;
            default:
                break;
        }
        lsvSearchResults.SortExpressions.AddSortExpression(sortExp);
        lsvSearchResults.Rebind();
    }
于 2012-06-08T20:36:48.187 に答える