Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 映射表达式<;Func<;Dto、bool>&燃气轮机;表达<;Func<;实体,bool>&燃气轮机;使用自动映射器_C#_Linq_Automapper - Fatal编程技术网

C# 映射表达式<;Func<;Dto、bool>&燃气轮机;表达<;Func<;实体,bool>&燃气轮机;使用自动映射器

C# 映射表达式<;Func<;Dto、bool>&燃气轮机;表达<;Func<;实体,bool>&燃气轮机;使用自动映射器,c#,linq,automapper,C#,Linq,Automapper,我有一个repository->service体系结构,它使用LINQ表达式过滤许多数据。存储库使用DTO处理实体和服务。目前,我使用Automapper将实体映射到dto,反之亦然。在存储库中,我有一个接受表达式>LINQ表达式的方法。服务使用表达式>LINQ表达式调用此方法。因此,我使用Automapper将服务的表达式映射到存储库的表达式。 项目成功构建,但运行时出现错误 这是在服务中引发错误的方法: public IQueryable<TDto> GetBy(Expressi

我有一个repository->service体系结构,它使用LINQ表达式过滤许多数据。存储库使用DTO处理实体和服务。目前,我使用Automapper将实体映射到dto,反之亦然。在存储库中,我有一个接受表达式>LINQ表达式的方法。服务使用表达式>LINQ表达式调用此方法。因此,我使用Automapper将服务的表达式映射到存储库的表达式。 项目成功构建,但运行时出现错误

这是在服务中引发错误的方法:

public IQueryable<TDto> GetBy(Expression<Func<TDto, bool>> predicate)
            => this.Repository.GetBy(Mapper.Map<Expression<Func<TEntity, bool>>>(predicate))
                .ProjectTo<TDto>(Mapper.ConfigurationProvider);
此外,我还尝试显式映射表达式:

CreateMap<Expression<Func<TEntity, bool>>, Expression<Func<TDto, bool>> >();

CreateMap<Expression<Func<TDto, bool>>, Expression<Func<TEntity, bool>>>();

有人有可能的解决方案吗?

我从未见过自动转换lambda的功能。 您应该做的是尝试使用
Project
方法

例如:

var predicate = new Func<Dto, bool>(d => d.Id == 2);
var query = mapper.ProjectTo<Dto>(entities, null).Where(predicate);
您可以做的另一件事是自己映射表达式。作为起点,您可以使用
Project
方法生成的查询:

var query = mapper.ProjectTo<Dto>(entities, null);
var lambda = (LambdaExpression)((UnaryExpression)((MethodCallExpression) query.Expression).Arguments[1]).Operand;
var body = (MemberInitExpression)lambda.Body;
var bindings = body.Bindings;

完美的这个解决方案真的解决了我的问题!我所做的唯一一件事就是改用接口IMapper。非常感谢你!
CreateMap<Expression<Func<TEntity, bool>>, Expression<Func<TDto, bool>> >();

CreateMap<Expression<Func<TDto, bool>>, Expression<Func<TEntity, bool>>>();
System.InvalidOperationException: 'Code supposed to be unreachable'
var predicate = new Func<Dto, bool>(d => d.Id == 2);
var query = mapper.ProjectTo<Dto>(entities, null).Where(predicate);
var query = entities
    .Select(e => new Dto { Id = e.Id, [...] }) // mapping created using map registered in AutoMapper
    .Where(d => d.Id == 2)
var query = mapper.ProjectTo<Dto>(entities, null);
var lambda = (LambdaExpression)((UnaryExpression)((MethodCallExpression) query.Expression).Arguments[1]).Operand;
var body = (MemberInitExpression)lambda.Body;
var bindings = body.Bindings;
public static class MapperExtensions
{
    public static Expression<Func<TEntity, bool>> ConvertPredicate<TDto, TEntity>(this Mapper mapper, Expression<Func<TDto, bool>> predicate)
    {
        return (Expression<Func<TEntity, bool>>)new PredicateVisitor<TDto, TEntity>(mapper).Visit(predicate);
    }

    public class PredicateVisitor<TDto, TEntity> : ExpressionVisitor
    {
        private readonly ParameterExpression _entityParameter;
        private readonly MemberAssignment[] _bindings;

        public PredicateVisitor(Mapper mapper)
        {
            IQueryable<TDto> mockQuery = mapper.ProjectTo<TDto>(new TEntity[0].AsQueryable(), null);
            LambdaExpression lambdaExpression = (LambdaExpression)((UnaryExpression)((MethodCallExpression) mockQuery.Expression).Arguments[1]).Operand;

            this._bindings = ((MemberInitExpression)lambdaExpression.Body).Bindings.Cast<MemberAssignment>().ToArray();
            this._entityParameter = Expression.Parameter(typeof(TEntity));
        }

        // This is required to modify type parameters
        protected override Expression VisitLambda<T>(Expression<T> node)
        {
            return Expression.Lambda(
                base.Visit(node.Body),
                node.Parameters.Select(p => (ParameterExpression)base.Visit(p)).ToArray()
            );
        }

        // Do member mapping
        protected override Expression VisitMember(MemberExpression node)
        {
            MemberInfo member = node.Member;
            MemberAssignment binding = this._bindings.FirstOrDefault(b => b.Member == member);

            if (binding != null)
            {
                return base.Visit(binding.Expression);
            }

            return base.VisitMember(node);
        }

        // Replace parameters reference
        protected override Expression VisitParameter(ParameterExpression node)
        {
            if (node.Type == typeof(TDto))
            {
                return this._entityParameter;
            }
            if (node.Type == typeof(TEntity))
            {
                return this._entityParameter;
            }

            return base.VisitParameter(node);
        }
    }
}