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));
}
私がやろうとしたが機能しなかったのは、文字列の配列を関数に渡し、クエリの先頭にインクルードを「追加」しようとしたことです。 GetQueryWithIncludeを呼び出し、一度にエンティティ名(実際にはナビゲーションプロパティ)を渡してクエリの結果を集計するとどうなるのかと思っていましたが、各呼び出しでクエリの結果が重複するのではないかと心配しています...これを機能させるための最良の方法は何だと思いますか?
前もって感謝します!
更新:
これが私が達成しようとしていることの例です:
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 Assemblyで利用可能です。上位層でそのアセンブリを参照したくない場合は、データアクセスアセンブリでラッパー拡張メソッドを作成します。
ここに例を示します:
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));
このクエリは、すべての顧客に住所と注文をロードし、すべての注文には注文アイテムが含まれます。
ハードコードされたObjectQuery(T).Include呼び出しに別れを告げます
EF> 4を使用している場合、組み込みです。 MSDNのDbExtensions.Include を確認してください。
//ここに最低限必要なものを含めました。以下に使用方法を示します。
IQueryable<File> xg= UnitOfWork.Files.GetAllLazyLoad(d => d.FileId == 1,
r => r.FileCategory);
//where r.FileCategory is a navigational property.
//Interface
namespace Msh.Intranet.Repository.GenericRepoPattern
{
public interface IRepository<T> where T:class
{
IQueryable<T> GetAllLazyLoad(Expression<Func<T, bool>> filter, params Expression<Func<T, object>>[] children);
}
}
namespace Msh.Intranet.Repository.GenericRepoPattern
{
/// <summary>
/// The EF-dependent, generic repository for data access
/// </summary>
/// <typeparam name="T">Type of entity for this Repository.</typeparam>
public class EFRepository<T> : IRepository<T> where T : class
{
public EFRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public virtual IQueryable<T> GetAllLazyLoad(Expression<Func<T, bool>> filter, params Expression<Func<T, object>>[] children)
{
children.ToList().ForEach(x=>DbSet.Include(x).Load());
return DbSet;
}
}
}