简体   繁体   中英

How can I convert lambda expression parameter type to another generic type?

I have repository model like the following.

using System;
using System.Linq;
using System.Linq.Expressions;
using MyProject.DAL.Interface;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;

namespace MyProject.DAL.Infrastructure
{
    public class BaseRepository<T>: IRepository<T> where T: class 
    {
        private readonly DbContext _dbContext;
        private readonly DbSet<T> _dbSet;

        public BaseRepository(DbContext context)
        {
            _dbContext = context ?? throw new ArgumentNullException("Context not be null");
            _dbSet = context.Set<T>(); 
        }

        public IQueryable<T> GetAll() => _dbSet;

        public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate) => _dbSet.Where(predicate);

        public T Get(Expression<Func<T, bool>> predicate) => _dbSet.Where(predicate).SingleOrDefault();


        // ....
    }
}

and i have service codes like the following

using System;
using System.Linq;
using System.Linq.Expressions;
using MyProject.DTO.Extensions;
using MyProject.DAL.Interface;
using MyProject.Service.Interface;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;

namespace MyProject.Service.Infrastructure
{
    public class BaseService<T, U>: IService<U> 
        where T: class 
        where U: class
    {
        protected IRepository<T> Repository;
        protected IUnitOfWork UnitOfWork;

        public U Get(Expression<Func<U, bool>> predicate) => Repository.Get(predicate); // -> Giving Error

        public U GetById(int id) => Repository.GetById(id).MapTo<U>();

        public void Add(U entity) => Repository.Add(entity.MapTo<T>());

        // ...
    }
}

When i want to use Get method in service class like this;

public U Get(Expression<Func<U, bool>> predicate) => Repository.Get(predicate);

it's giving error, because repository wating T model but sending in service, U model.

How can i convert predicate type from ( Expression<Func<U, bool>> ) to ( Expression<Func<T, bool>> ) ?

I don't know what is the types you are passing into U and T since you have no sample how you populate your base class. So i am guessing one is entity and the other one is DTO that maps to entity. It is possible to write dynamic expression that calls mapper to map the expressions parameter into desired type to T but it would be hard and will require reflection and expression shenanigans. SO my suggestion is to convert your function signature into this :

public U Get(Expression<Func<T, bool>> predicate) => Repository.Get(predicate).MapTo<U>;

Since it is only an expression and it won't change how you call the function if the mapped types are similar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM