1

私は次のようなものを含むドメインモデルを持っています:

public class Customer : EntityBase<Customer>, IAggregateRoot
{
    public IList<Comment> Comments { get; set; }
}

public class Comment : EntityBase<Comment>
{
    public User CreatedBy { get; set; }
    public bool Private { get; set; }
}

これらのエンティティを取得するためのサービスレイヤーがあり、そのサービスレイヤーに渡される引数の中には、要求元のユーザーが誰であるかが含まれます。

私がやりたいのは、特定の顧客に返されるアイテムDetachedCriteriaを制限するサービスレイヤーを構築できるようにすることCommentです。これにより、ユーザーには、それらに属さず、プライベートとしてマークされたコメントは表示されません。

私はこのようなことをしてみました:

criteria.CreateCriteria("Comments")
    .Add(Restrictions.Or(Restrictions.Eq("Private", false),
                         Restrictions.And(Restrictions.Eq("Private", true),
                                          Restrictions.Eq("CreatedBy.Id", requestingUser.Id))));

しかし、これは遅延ロードされたコメントには流れません。

フィルタを使用したくないのは、セッション(現在サービスレイヤーに公開されていない)と対話するか、リポジトリにユーザーコンテキストについて認識させる必要があるためです(これは、必要なロジックが多すぎるようです)。ダムレイヤー)。フィルタは、他の理由でも汚い解決策です。何が表示され、何が表示されないかを決定するロジックは、単なるプライベートフラグよりも詳細です。

コレクションをフィルタリングするためにサービスレイヤーでLINQを使用したくないのは、そうすると、遅延読み込みの利点全体が非常に悪い方法で吹き飛ばされるためです。コメントが関連していない顧客のリストは、非常に遅いデータベース呼び出しの嵐を引き起こします。プレゼンテーション層(MVCアプリ)でLINQを使用するのは、間違った場所のように思われるため、使用したくありません。

これが?を使用して可能かどうかのアイデアはありDetachedCriteriaますか?これを達成する他の方法はありますか?

4

1 に答える 1

1

エンティティ自体に、外部値に基づいてコレクションプロパティの異なる値のセットを公開させることは、私には正しくないようです。

これは、リポジトリサービスへの直接の呼び出しとして、またはエンティティ自体を介して、これを具体的に行うためのメソッドを作成することによって、より適切に処理されます。

ただし、現在のモデルに最適に適合させるために、エンティティを取得するために現在行っている呼び出しで、エンティティだけでなくビューモデルを返すようにします。

public class PostForUser
{
    public Post Post {get; set;}
    public User User {get; set;}
    public IList<Comment> Comments}
}

そして、あなたのサービス方法で(私はここでいくつかの推測をしています)

public PostForUser GetPost(int postId, User requestingUser){

   ...
}

次に、PostForUserビューモデルを最も効率的な方法で作成し、データを入力します。おそらく、分離された条件、または単一のクエリとDistinctRootEntity Transformerを使用します(実際のコメントプロパティは、おそらく使用しないため、遅延読み込みのままにしておくことができます)。それ)

于 2011-10-16T21:42:22.197 に答える