0

我正在使用 Entity Framework 6,并且已经实现了一些类似的存储库模式。最初,我的存储库具有类似GetAll返回的函数,IEnumerable以避免过多地泄漏数据层抽象。但是,我的服务层是我的存储库的包装器并包含业务逻辑,需要对查询进行更多控制。控制,例如急切加载相关实体,仅选择某些列等。因此,为了避免仅将 DbContext 暴露给我的服务层,我调整了存储库,以便它们现在返回IQueryable,以便服务层可以执行链之类的操作Includes 到查询等上。

问题是我的存储库有一个返回单个实体的方法,而该函数只返回实体的 POCO。这些是最有可能需要急切加载的函数,调用Include. 显然,不能在 POCO 之外做到这一点。

是否有类似IQueryable单个实体的附加Include逻辑链接等?还是一种调整此逻辑以允许这样做的方法?我的一个存储库的示例是这样的:

namespace Portal.Repositories
{
    public class UploadRepository : IUploadRepository
    {
        private readonly IPortalContext m_context;

        public UploadRepository(IPortalContext context)
        {
            m_context = context;
        }

        #region Methods

        public int Count(Expression<Func<Upload, bool>> predicate)
        {
            return m_context.Uploads.Count(predicate);
        }

        public Upload Get(Expression<Func<Upload, bool>> predicate)
        {
            return m_context.Uploads.FirstOrDefault(predicate);
        }

        public Upload Insert(Upload entity)
        {
            return m_context.Uploads.Add(entity);
        }

        public Upload Delete(Upload entity)
        {
            return m_context.Uploads.Remove(entity);
        }

        public IQueryable<Upload> All()
        {
            return m_context.Uploads;
        }

        public IQueryable<Upload> Where(Expression<Func<Upload, bool>> predicate)
        {
            return m_context.Uploads.Where(predicate);
        }

        #endregion
    }
}

您可以看到我的Get方法,以及我的服务如何无法选择何时执行Include或不执行,因为它只返回一个 POCO。

4

2 回答 2

1

您可以向存储库添加一些功能以传递一些包含表达式。

使用 System.Data.Entity;

命名空间 Portal.Repositories
{
  公共类 UploadRepository : IUploadRepository
  {
    公开上传获取(
      表达式<Func<Upload, bool>> 谓词,
      参数 Expression<Func<Upload, object>>[] includeExpressions)
    {
      var uploads = m_context.Uploads;
      foreach(包含表达式中的变量 i)
        上传 = uploads.Include(i);
      返回 uploads.FirstOrDefault(predicate);
    }
  }
}
于 2013-10-29T18:49:30.203 回答
1

这个怎么样:

public List<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
                         Func<IQueryable<TEntity>, IOrderedEnumerable<TEntity>> orderBy = null,
                                     string includeProperties = "")
    {
        IQueryable<TEntity> query = DbSet;
        if (filter != null)
        {
            query = query.Where(filter);
        }

        query = includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, includeProperty) => current.Include(includeProperty));

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

[编辑]:这是我目前在自己的代码中使用的。您需要更改和调整代码以适合您的目的,但想法是将 Include 属性作为逗号分隔值传递给您的 Get 函数。

于 2013-10-29T18:39:32.183 回答