1. ホーム
  2. c#

EF 他のエンティティを含む (Generic Repositoryパターン)

2023-08-13 07:34:04

質問

私は、Entity Framework Code Firstの上でGeneric Repositoryパターンを使用しています。私がクエリでより多くのエンティティを含める必要があるまで、すべてがうまくいっていました。私は1つのエンティティをうまく含めることができましたが、今私は複数のエンティティを含める方法を見つけ出すことができません。私がこれまでに得たものを確認してください。

public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
    var entityName = GetEntityName<TEntity>();
    return _objectContext.CreateQuery<TEntity>(entityName);
}

public IList<TEntity> GetQueryWithInclude<TEntity>(string toInclude) where TEntity : class
{
    var entityName = GetEntityName<TEntity>();
    return _objectContext.CreateQuery<TEntity>(entityName).Include(toInclude).ToList();
}

private string GetEntityName<TEntity>() where TEntity : class
{
    return string.Format("{0}.{1}", _objectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(TEntity).Name));
}

私が行おうとしたがうまくいかなかったことは、関数に文字列の配列を渡し、それからクエリの上に "append"を追加しようとしたことです。GetQueryWithIncludeを呼び出して、クエリの結果を集約するために一度にエンティティ名(実際にはナビゲーション・プロパティ)を渡したらどうかと思いましたが、これでは呼び出しごとにクエリの結果が複製されるのではないかと心配です...。これを動作させるための最良の方法は何だと思いますか?

事前にありがとうございます!

UPDATEです。

私が実現しようとしていることの一例です。

public IQueryable GetQueryWithIncludes(string[] otherEntities)
{
    var entityName = GetEntityName<TEntity>();
    //now loop over the otherEntities array 
    //and append Include extensions to the query
    //so inside the loop, something like: 
    _objectContext.GetQuery<TEntity>(entityName).Include(otherEntities[index]);
}

どのように解決するのですか?

IQueryableのInclude拡張だけを使用します。これは、EF 4.1 アセンブリで利用可能です。上位層でそのアセンブリを参照したくない場合は、データアクセスアセンブリでラッパー拡張メソッドを作成します。

以下に例を示します。

public static IQueryable<T> IncludeMultiple<T>(this IQueryable<T> query, params Expression<Func<T, object>>[] includes)
    where T : class
{
    if (includes != null)
    {
        query = includes.Aggregate(query, 
                  (current, include) => current.Include(include));
    }

    return query;
}

などと使うことになります。

var query = context.Customers
                   .IncludeMultiple(
                       c => c.Address,
                       c => c.Orders.Select(o => o.OrderItems));

このクエリは、すべての顧客の住所と注文を読み込み、すべての注文はその注文項目を含むことになります。