Some background: I have in my application multiple layers, two of which are a domain layer and an infrastructure layer which serves as my DAL. In the domain layer, I have implemented a generic repository pattern as such:
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);
}
In my DAL I have a generic DAO pattern implemented as such:
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);
}
I have a domain class that represents, in business terms, an individual. I have a similar individual object in my DAL layer that is used to represent the object in my database. I have a class called EntityFrameworkDao that implements my IDAO interface and is responsible for all of the actions found in that DAO interface (CRUD and some other actions as described above).
I am trying (days of trying) to find a way to map the expression that is used in the repository to the expression used in the DAL. The specific example is this: I have a generic DomainRepository that implements my IRepository interface (see above). The SearchFor method looks like this:
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();
}
I need to figure out what SomeMagicFunctionToConvertExpressions is so that I can convert the predicate in my domain layer to something that the Where method can understand in my DAL class that implements IDao:
public IQueryable<TEfEntity> Where(Expression<Func<TEfEntity, bool>> predicate)
{
return _context.Set<TEfEntity>().Where(predicate).AsQueryable();
}
I have tried using Automapper's CreateMapExpression as found in this article: AutoMapper for Func's between selector types
But that only tells me how to convert between Func<DomainType,bool>
predicate to Func<DTOType,bool>
(predicate), not Expression to Expression. I am looking for a way to convert something like this:
Expression<Func<TDomainEntity, bool>> predicate
To this:
Expression<Func<TDAOEntity, bool>> predicate
I thought I was on to something after I found this article about mutiating expression trees, but it won't allow me to pass in a compex linq expression that contains && or || or anyting more complex than a simple i => i.id.Equals(12345) type query.
I am using Automapper, so any solutoins using that would be great, but I am open to any ideas at this point. I really am stuck and have been researching this for days now. It seems like a fairly common task: convert a query based on a type from one layer in the architecture to a type used in the DAL.
Thanks in advance for your help.