先日、こんな質問をしました。
リポジトリ層はデータ転送オブジェクト (DTO) を返す必要がありますか?
答えは (たった 1 人によるものですが、それは良い考えではないという予感が既にありました)、いいえ、リポジトリは後で DTO オブジェクトを処理する必要はないというものでした (それらの目的は純粋にサーバー経由で送信されることです)。ワイヤー) であり、サービス層がそれを処理する必要があります。
今、私はその間にあなたの意見が必要な構造を思いついた. その考えは、そうするのが理にかなっている場合、リポジトリ層は、私が定義した と呼ばれるインターフェースタイプを返すことができるということIProjectable
です。これはクエリをラップします(リポジトリレイヤーはまだクエリを実行しません)が、消費者がクエリを変更することはできません(それはそうではありません)IQueryable
。実際にクエリを実行します。First
ToPagedList
したがって、リポジトリでは次のようになります。
public IProjectable<User> GetUser(int id)
{
var query = from u in Set<User>()
where u.UserID == id
select u;
return query.AsProjectable();
}
そして、サービス層では次のようになります:
var dto = repository.GetUser(16).Single(u => new SimpleUserDto
{
FullName = u.FirstName + " " + u.LastName,
DisplayAddress = u.Address.Street + u.Address.HouseNumber,
OrderCount = u.Orders.Count()
});
return dto;
ここで実際のデータアクセスを行うことは、依然としてリポジトリレイヤーの責任であり(そうあるべきです)、シリアライズ可能なフォームへの射影はサービスレイヤーの責任である(そうあるべきである)というのは正しいですか?
これを効率的に行うための他の唯一の方法(User
リポジトリからa を返しCount()
、Orders
サービス層でこれを実行すると、データベースへの余分なクエリが発生します) は、これらすべてのプロパティを持つ型を定義し、これは、「純粋さ」のために同じ名前を付けていないだけで DTO と同じであるため、ばかげているように思えます。このようにして、私は自分のケーキを持って、ほとんどの場合それを食べることができるようです.
私が見る欠点は、サービスレイヤーが実際にSQLに変換できないプロジェクションを実行する場所で不一致が発生する可能性があることです。これは心配する必要はありません.実際のデータアクセスを行います。
ところで、私は Entity Framework 4 を使用しています。