【问题标题】:How can I convert lambda expression parameter type to another generic type?如何将 lambda 表达式参数类型转换为另一种泛型类型?
【发布时间】:2019-11-24 18:00:27
【问题描述】:

我有如下的存储库模型。

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();


        // ....
    }
}

我有如下服务代码

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>());

        // ...
    }
}

当我想在这样的服务类中使用 Get 方法时;

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

它给出了错误,因为存储库正在等待 T 模型但正在发送服务,U 模型。

如何将谓词类型从 (Expression&lt;Func&lt;U, bool&gt;&gt;) 转换为 (Expression&lt;Func&lt;T, bool&gt;&gt;)?

【问题讨论】:

    标签: c# generics lambda type-conversion expression


    【解决方案1】:

    我不知道您传递给 U 和 T 的类型是什么,因为您没有示例如何填充基类。所以我猜一个是实体,另一个是映射到实体的 DTO。可以编写动态表达式,调用 mapper 将表达式参数映射到所需的类型到 T,但这会很困难,并且需要反射和表达式恶作剧。所以我的建议是将你的函数签名转换成这个:

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

    因为它只是一个表达式,如果映射类型相似,它不会改变你调用函数的方式

    【讨论】:

      猜你喜欢
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多