5

私は Entity Framework 5 を使用しており、以下の 2 つの Get() メソッドのようないくつかのメソッドがある汎用リポジトリがあります。

public TEntity GetById(int id)
{
    return DbSet.Find(id);
}

public TEntity Get(
    Expression<Func<TEntity, bool>> filter = null,
    IEnumerable<string> includePaths = null)
{
    IQueryable<TEntity> query = DbSet;

    if (filter != null)
    {
        query = query.Where(filter);
    }

    if (includePaths != null)
    {
        query = includePaths.Aggregate(query, (current, includePath) => current.Include(includePath));
    }

    return query.SingleOrDefault();
}

これらはどちらも非常に役立ちますが、次のように、もう少し複雑な GetById() 呼び出しを行い、同時にいくつかのエンティティ参照を取得したい場合に役立ちます。

var user = _userRepository.GetById(
    id,
    new List<string> { "Roles", "Invoices" });

ラムダの特定の Id フィールド、つまり UserId や InvoiceId などにアクセスできるように、エンティティごとにエンティティ固有の (一般的ではない) GetById(id, includes) 呼び出しをロールアウトする必要があります。

public User GetById(
    int id,
    IEnumerable<string> includes)
{
    return Get(
        (u => u.UserId == id),
        includes);
}

私の平均的な EF スキルでは、DbSet.Find(id) の良さと .Include() 呼び出しを一般的な方法で組み合わせる方法を理解できないようです。

問題は、ID でエンティティを取得し、いくつかの参照を含めるために使用できるジェネリック EF メソッドを記述し、エンティティ固有の GetById(id, includes) 呼び出しを記述する必要をなくす方法があるかどうかです。上記を行いました。

前もって感謝します。

4

1 に答える 1

8

私の一般的なリポジトリでそれを行う方法は次のとおりです。

    public T GetBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes)
    {
        var result = GetAll();
        if (includes.Any())
        {
            foreach (var include in includes)
            {
                result = result.Include(include);
            }
        }
        return result.FirstOrDefault(predicate);
    }

これは、検索ではなくラムダ インクルードと FirstOrDefault を使用していることに注意してください。ただし、結果は同じです。

ここで、私の汎用リポジトリの完全なソースを確認できます。

これは、次の方法で呼び出すことができます。

var entity = myRepository.GetBy(e=>e.Id == 7, /*Includes*/ e=> e.ANavigationProperty, e=>e.AnotherNavProperty);

編集:

汎用リポジトリはもう使用しません。代わりに、拡張メソッドを使用してその場でクエリを作成します。これにより、再利用が大幅に改善されることがわかりました。(コンポーザブルリポジトリに関する私の記事を参照してください)

于 2013-01-15T19:43:17.937 に答える