-
Notifications
You must be signed in to change notification settings - Fork 54
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Hello,
I'm stuck with a specific scenario in ExpressionMapper.
In the reproduction code below (a simple console app), in the last mapping I have an ArgumentException saying "Property 'System.DateTime EventDate' is not defined for Type TestExpressionMapper.EventEntity" which is obviously wrong since the property exists on the class. Is there any mistake in my code or in the way i'm using ExpressionMapper or is it a non-covered scenario ? If so, is there a known workaround ?
Thanks !
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 = 9, 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; }
}
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working