简体   繁体   English

如何将 lambda 表达式参数类型转换为另一种泛型类型?

[英]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;当我想在这样的服务类中使用 Get 方法时;

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.它给出了错误,因为存储库等待 T 模型但正在发送服务 U 模型。

How can i convert predicate type from ( Expression<Func<U, bool>> ) to ( Expression<Func<T, bool>> ) ?如何将谓词类型从 ( Expression<Func<U, bool>> ) 转换为 ( 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.我不知道您传递给 U 和 T 的类型是什么,因为您没有如何填充基类的样本。 So i am guessing one is entity and the other one is DTO that maps to entity.所以我猜一个是实体,另一个是映射到实体的 DTO。 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.可以编写动态表达式,调用 mapper 将表达式参数映射到 T 所需的类型,但这会很困难,并且需要反射和表达式恶作剧。 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因为它只是一个表达式,如果映射类型相似,它不会改变你调用函数的方式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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