C# IQueryable功能,如Include,但针对单个实体?
我正在使用EntityFramework6,并实现了一些类似于存储库模式的功能。最初,我的存储库具有类似于C# IQueryable功能,如Include,但针对单个实体?,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,我正在使用EntityFramework6,并实现了一些类似于存储库模式的功能。最初,我的存储库具有类似于GetAll的函数,该函数返回一个IEnumerable,以避免数据层抽象泄漏过多。但是,我的服务层(它是我的存储库的包装器,包含业务逻辑)需要对查询进行更多的控制。控制,如急切加载相关实体、仅选择某些列等。因此,为了避免只向我的服务层公开DbContext,我调整了存储库,使它们现在返回IQueryable,以便服务层可以在查询中执行诸如chainIncludes等操作 问题是我的存储库有
GetAll
的函数,该函数返回一个IEnumerable
,以避免数据层抽象泄漏过多。但是,我的服务层(它是我的存储库的包装器,包含业务逻辑)需要对查询进行更多的控制。控制,如急切加载相关实体、仅选择某些列等。因此,为了避免只向我的服务层公开DbContext,我调整了存储库,使它们现在返回IQueryable
,以便服务层可以在查询中执行诸如chainInclude
s等操作
问题是我的存储库有一个返回单个实体的方法,而函数只返回实体的POCO。这些是最可能需要立即加载的函数,调用Include
。显然,在POCO上做不到
对于单个实体,是否有类似于IQueryable
的内容用于包含
逻辑等的附加链接?或者是一种调整这种逻辑的方法?我的存储库示例如下:
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
}
}
namespace Portal.Repositories
{
公共类UploadRepository:IUploadRepository
{
私有只读IPortalContext m_上下文;
公共上载存储库(IPortalContext上下文)
{
m_context=上下文;
}
#区域方法
公共整数计数(表达式谓词)
{
返回m_context.Uploads.Count(谓词);
}
公共上载Get(表达式谓词)
{
返回m_context.Uploads.FirstOrDefault(谓词);
}
公共上载插入(上载实体)
{
返回m_context.Uploads.Add(实体);
}
公共上载删除(上载实体)
{
返回m_context.Uploads.Remove(实体);
}
公共IQueryable All()
{
返回m_context.Uploads;
}
公共IQueryable Where(表达式谓词)
{
返回m_context.Uploads.Where(谓词);
}
#端区
}
}
您可以看到我的Get
方法,以及我的服务如何无法选择何时包含或不包含,因为它只返回一个POCO。这样如何:
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();
}
}
public List Get(表达式过滤器=null,
Func orderBy=null,
字符串includeProperties=“”)
{
IQueryable query=DbSet;
if(过滤器!=null)
{
query=query.Where(过滤器);
}
query=includeProperty.Split(新字符[]{',},StringSplitOptions.RemoveEmptyEntries)。聚合(query,(current,includeProperty)=>current.Include(includeProperty));
if(orderBy!=null)
{
returnorderby(query.ToList();
}
其他的
{
返回query.ToList();
}
}
[编辑]:这是我目前在自己的代码中使用的内容。您需要更改和调整代码以符合您的目的,但我们的想法是将Include属性作为逗号分隔的值传递给Get函数。您可以向存储库添加一些功能以传递一些Include表达式
using System.Data.Entity;
namespace Portal.Repositories
{
public class UploadRepository : IUploadRepository
{
public Upload Get(
Expression<Func<Upload, bool>> predicate,
params Expression<Func<Upload, object>>[] includeExpressions)
{
var uploads = m_context.Uploads;
foreach (var i in includeExpressions)
uploads = uploads.Include(i);
return uploads.FirstOrDefault(predicate);
}
}
}
使用System.Data.Entity;
名称空间门户.Repositories
{
公共类UploadRepository:IUploadRepository
{
公共上传获取(
表达式谓词,
参数表达式[]includeExpressions)
{
var uploads=m_context.uploads;
foreach(includeExpressions中的var i)
上传=上传。包括(i);
返回上载。FirstOrDefault(谓词);
}
}
}
我想我可以一起删除Get
存储库方法,强制我的服务使用all
或Where
,然后自己调用FirstOrDefault
。我喜欢这个。我要试试看!