5

ここに概説されているように、Linqを使用して仕様パターンを実装しましたhttps://www.packtpub.com/article/nhibernate-3-using-linq-specifications-data-access-layer

私は今、熱心な負荷をかける機能を追加したいと思っていますが、それを実行するための最良の方法がわかりません。

リンクされた例の汎用リポジトリクラス:

public IEnumerable<T> FindAll(Specification<T> specification)
{
  var query = GetQuery(specification);
  return Transact(() => query.ToList());
}

public T FindOne(Specification<T> specification)
{
  var query = GetQuery(specification);
  return Transact(() => query.SingleOrDefault());
}

private IQueryable<T> GetQuery(
  Specification<T> specification)
{
  return session.Query<T>()
    .Where(specification.IsSatisfiedBy());
}

そして仕様の実装:

public class MoviesDirectedBy : Specification<Movie>
{

 private readonly string _director;

 public MoviesDirectedBy(string director)
 {
   _director = director;
 }

 public override
    Expression<Func<Movie, bool>> IsSatisfiedBy()
 {
   return m => m.Director == _director;
 }
}

これはうまく機能しています。今度は、熱心にロードできる機能を追加したいと思います。NHibernateの積極的な読み込みは、クエリでFetchを使用して実行できることを理解しています。

私が探しているのは、熱心な読み込みロジックを仕様内にカプセル化するか、それをリポジトリに渡すか、そしてこれを実現するために必要なLinq /式ツリー構文(つまり、それがどのように行われるかの例)です。

4

2 に答える 2

3

考えられる解決策は、Specificationクラスを拡張して以下を追加することです。

public virtual IEnumerable<Expression<Func<T, object>>> FetchRelated
{
    get
    {
        return Enumerable.Empty<Expression<Func<T, object>>>();
    }
}

GetQueryを次のように変更します。

        return specification.FetchRelated.Aggregate(
            session.Query<T>().Where(specification.IsSatisfiedBy()),
            (current, related) => current.Fetch(related));

今、あなたがしなければならないのは、必要なときにFetchRelatedをオーバーライドすることです

public override IEnumerable<Expression<Func<Movie, object>>> FetchRelated
{
    get
    {
        return new Expression<Func<Movie, object>>[]
                     {
                         m => m.RelatedEntity1,
                         m => m.RelatedEntity2
                     };
    }
}

私が今書いたこの実装の重要な制限は、ルートエンティティに直接関連するエンティティのみをフェッチできることです。

改善点は、(を使用して)任意のレベルをサポートするThenFetchことです。これには、ジェネリックスの操作方法にいくつかの変更が必要になります(以前はobject、さまざまなエンティティタイプを簡単に組み合わせることができました)

于 2010-12-06T16:25:29.113 に答える
1

Fetch()呼び出しは必要ないので、仕様に入れたくないでしょう。仕様は、コードのさまざまな部分で共有できるデータを制限するためのものですが、他の部分では、ユーザーに提示するデータのニーズが大幅に異なる可能性があるため、それらの時点で追加します。ステートメントをフェッチします。

于 2010-12-16T03:01:38.960 に答える