3

ハイドレーションが必要な子オブジェクトの式を渡すことにより、リポジトリに一種の熱心な読み込み機能を実装しようとしています。

    Candidate Get(int candidateId, params Expression<Func<Candidate, object>>[] includes);

したがって、私のサービスは次のようなもので呼び出すことができます:

        candidateRepository.Get(1, p => p.Notes, p => p.Profile, p => p.Application);

Notes、Profile、および Application はすべて Candidate のプロパティです。このようなもの:

    public class Candidate
    {
        public string Name { get; set; }

        public IList<CandidateNote> Notes { get; set; }

        public Profile Profile { get; set; }

        public Application Application { get; set; }
    }

そのため、リポジトリ内で、プロパティが式 params に渡されたかどうかを判断して、実際にハイドレートを試みる必要があります。しかし、これを達成するためのエレガントな方法は見当たりません。

    public Candidate Get(int candidateId, params Func<Candidate, object>[] includes)
    {
        ...

        if (candidate.Notes property was specified?)
        {
           candidate.Notes = this.candidateNoteRepository.List(candidateId);
        }

        return candidate;
    }

を介して式からプロパティ名を取得できるようです(includes[0].Body as MemberExpression).Member.Nameが、もっと簡単な方法があるはずです。さらに、私は文字列比較のファンではありません。私がしなければならない場合を除いて、私は本当にこのようにしたくありません:

        if (includes[0].Body as MemberExpression).Member.Name == "Notes")
        {

それは次のような非常に単純なものであるべきだと思われます

        if (includes[0].Is(candidate.Notes) or includes[0](candidate.Notes).Match())
        {

それが発生した場合に備えて、インクルードを式の配列として保持したいと思います。なぜなら、私は現在 ADO.NET を使用していますが、最終的には Entity Framework の方法に移行する予定であり、これらの式は非常にうまく機能するからです。 Include メソッドを使用します。

        return this.Filter(m => m.Candidates.CandiateId == candidateId)
            .Include(includes[0])
4

2 に答える 2

0

あなたが言うように、文字列比較は簡単に拡張できないため、良い方法ではありません。メンバーをより詳しく調べて、有効なインクルードかどうかを判断できます。
1 つのオプションは、プロパティの戻り値の型を確認することです。IEnumerable から派生したものである場合は、有効なインクルードである可能性があります。
決定の基礎となる必要な事実がプロパティ自体に見つからない場合は、カスタム属性を使用して、クラスに含めるプロパティをマークできます。次に、可能なインクルードの CustomAttributes プロパティをチェックして、それが有効なインクルードかどうかを判断できます。

于 2013-10-28T15:20:52.137 に答える