ExpressionMapper:无法在特定场景下实现 lambda 映射

ExpressionMapper : Cannot achieve lambda mapping in specific scenario

我是一个快乐的 ExpressionMapper 新用户,但我受困于这个特定场景。

    public class TestExpressionMapper
    {
        private static IMapper _mapper;

        static void Main()
        {
            #region Populate test

            List<EmployeeEntity> empEntity = new List<EmployeeEntity>
            {
                new EmployeeEntity { Id = 1, Name = "Jean-Louis", Age = 39, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-1) } }.ToList() },
                new EmployeeEntity { Id = 2, Name = "Jean-Paul", Age = 32, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-2) } }.ToList() },
                new EmployeeEntity { Id = 3, Name = "Jean-Christophe", Age = 19, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-1) } }.ToList() },
                new EmployeeEntity { Id = 4, Name = "Jean-Marie", Age = 27, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-3) } }.ToList() },
                new EmployeeEntity { Id = 5, Name = "Jean-Marc", Age = 22, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-5) } }.ToList() },
                new EmployeeEntity { Id = 5, Name = "Jean-Pierre", Age = 22, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-5) } }.ToList() },
                new EmployeeEntity { Id = 6, Name = "Christophe", Age = 55, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-1) } }.ToList() },
                new EmployeeEntity { Id = 7, Name = "Marc", Age = 23, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-2) } }.ToList() },
                new EmployeeEntity { Id = 8, Name = "Paul", Age = 38, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-10) }, new EventEntity { EventType = "Stop", EventDate = DateTime.Today.AddYears(-1) } }.ToList() },
                new EmployeeEntity { Id = 8, Name = "Jean", Age = 32, Events = new EventEntity[]{ new EventEntity { EventType = "Start", EventDate = DateTime.Today.AddYears(-10) }, new EventEntity { EventType = "Stop", EventDate = DateTime.Today.AddYears(-2) } }.ToList() },
            };

            #endregion

            #region Mapping config

            _mapper = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<EmployeeModel, EmployeeEntity>().ReverseMap();
                cfg.CreateMap<EventModel, EventEntity>().ReverseMap();
            }).CreateMapper();

            _mapper.ConfigurationProvider.AssertConfigurationIsValid();

            #endregion

            #region Test

            Expression<Func<EmployeeModel, bool>> filter;
            Expression<Func<EmployeeEntity, bool>> mappedFilter;

            // Works : Returns employees whose name starts with "Jean"
            filter = emp => emp.Name.StartsWith("Jean");
            mappedFilter = _mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
            var res1 = empEntity.AsQueryable().Where(mappedFilter);

            //Works : Returns employees having at least one "Stop" event
            filter = emp => emp.Events.Any(evt => evt.EventType.Equals("Stop"));
            mappedFilter = _mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
            var res2 = empEntity.AsQueryable().Where(mappedFilter);

            //Works : Returns employees having any event older than 3 years
            filter = emp => emp.Events.Any(evt => evt.EventDate < DateTime.Today.AddYears(-3));
            mappedFilter = _mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
            var res3 = empEntity.AsQueryable().Where(mappedFilter);

            //Works : Returns employees having a stop event older than 1 year (no expression mapping -> lambda is built against entities)
            mappedFilter = emp =>
                emp.Events.Any(e => e.EventType.Equals("Stop")) &&
                emp.Events.First(e => e.EventType.Equals("Stop")).EventDate < DateTime.Today.AddYears(-1);
            var res4 = empEntity.AsQueryable().Where(mappedFilter);

            //Breaks on mapping : Same lambda as previous one but built against models then mapped
            filter = emp =>
                emp.Events.Any(e => e.EventType.Equals("Stop")) &&
                emp.Events.First(e => e.EventType.Equals("Stop")).EventDate < DateTime.Today.AddYears(-1);
            mappedFilter = _mapper.MapExpression<Expression<Func<EmployeeEntity, bool>>>(filter);
            var res5 = empEntity.AsQueryable().Where(mappedFilter);

            #endregion

            Console.ReadKey();
        }

    }

    internal class EmployeeEntity
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public List<EventEntity> Events { get; set; }
    }

    internal class EventEntity
    {
        public string EventType { get; set; }
        public DateTime EventDate { get; set; }
    }


    internal class EmployeeModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public List<EventModel> Events { get; set; }
    }

    internal class EventModel
    {
        public string EventType { get; set; }
        public DateTime EventDate { get; set; }
    }

在最后一个映射中,我有一个 ArgumentException 说 "Property 'System.DateTime EventDate' is not defined for Type TestExpressionMapper.EventEntity" 这显然是错误的,因为 属性 存在。 我的代码是否有任何错误,或者它是 ExpressionMapper 中未涵盖的场景?如果是这样,是否有任何解决方法? 谢谢!

这是 ExpressionMapper 中的错误。 使用版本 >= 3.0.2-preview01 解决了问题。

Github issue