私は、アセンブラーパターンを使用して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を表示するだけ)
- フィルタリング、ページングなどをサポート
- 健全なアーキテクチャの実装