一些背景信息:我的应用程序中有多个层,其中两个是领域层和基础设施层,后者作为我的数据访问层。在领域层中,我实现了一个通用的存储库模式,如下所示:
public interface IRepository<T, in TId> where T : IEntity<TId>
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(TId id);
}
在我的数据访问层(DAL)中,我实现了一个通用的DAO模式,如下所示:
public interface IDao<TEntity> where TEntity : class
{
IQueryable<TEntity> Select();
IQueryable<TEntity> GetAll();
IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);
TEntity GetSingle(Expression<Func<TEntity, bool>> predicate);
TEntity GetFirst(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void Delete(TEntity entity);
void Attach(TEntity entity);
}
我有一个领域类,代表业务术语中的个人。我在我的DAL层中有一个类似的个人对象,用于表示我的数据库中的对象。我有一个名为EntityFrameworkDao的类,实现了我的IDAO接口,并负责该DAO接口中找到的所有操作(CRUD和其他一些操作,如上所述)。
我正在尝试(尝试了几天)找到一种将存储库中使用的表达式映射到DAL中使用的表达式的方法。具体示例是这样的:我有一个通用的DomainRepository,实现了我的IRepository接口(见上文)。SearchFor方法看起来像这样:
public IQueryable<TDomainEntity> SearchFor(Expression<Func<TDomainEntity, bool>> predicate)
{
var convertedExpression = **SomeMagicFunctionToConvertExpressions**();
var dataEntities = _dao.Where(convertedExpression);
return AutoMapper.Mapper.Map<IEnumerable<TEfEntity>, IEnumerable<TDomainEntity>>(dataEntities).AsQueryable();
}
我需要找出一些魔术函数来转换表达式,这样我就能够在实现IDao的DAL类中使用Where方法,并将域层中的谓词转换为可理解的内容。
public IQueryable<TEfEntity> Where(Expression<Func<TEfEntity, bool>> predicate)
{
return _context.Set<TEfEntity>().Where(predicate).AsQueryable();
}
我尝试使用Automapper的CreateMapExpression,就像在这篇文章中所提到的那样:AutoMapper for Func's between selector types。但是这只告诉我如何在
Func<DomainType,bool>
谓词和Func<DTOType,bool>
(谓词)之间进行转换,而不是表达式与表达式之间的转换。我正在寻找一种将类似于这样的内容转换的方法:Expression<Func<TDomainEntity, bool>> predicate
到这个:
Expression<Func<TDAOEntity, bool>> predicate
我看到了这篇文章关于表达式树的变异,觉得很有帮助,但它不允许我传递包含&&或||或任何比简单的i => i.id.Equals(12345)查询更复杂的linq表达式。
我正在使用Automapper,所以任何使用它的解决方案都很好,但我现在对任何想法都持开放态度。我真的卡住了,已经研究了几天了。它似乎是一个相当常见的任务:将基于一种架构中的类型的查询转换为在DAL中使用的类型的查询。
提前感谢您的帮助。