EF Включая другие объекты (шаблон общего репозитория) - PullRequest
67 голосов
/ 21 марта 2011

Сначала я использую шаблон универсального репозитория поверх кода Entity Framework. Все работало нормально, пока мне не нужно было включить больше объектов в запрос. Я должен включить одну сущность успешно, но теперь я не могу понять, как включить несколько сущностей. Проверьте, что у меня так далеко:

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 и передавал имя сущности (на самом деле свойство навигации) одновременно, чтобы агрегировать результаты запроса, но я беспокоюсь, что это может дублировать результаты запроса при каждом вызове ... Как вы думаете, что будет лучшим способом заставить это работать?

Заранее спасибо!

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]);
}

Ответы [ 3 ]

129 голосов
/ 21 марта 2011

Используйте только расширение Include на IQueryable.Он доступен в сборке 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));

Этот запрос будет загружать всех клиентов с их адресами и заказами, и каждый заказ будет содержать элементы заказа.

3 голосов
/ 09 января 2013

// Я включил здесь минимум.Ниже описано, как его использовать.

     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;
                }

            }
        }
3 голосов
/ 02 мая 2011
...