Reputation: 435
I'm trying to use a custom value resolver in automapper to get the difference between 2 dates at run time.
The Resolver
public class TotalDaysResolver : ValueResolver<JobPersonnel, double>
{
protected override double ResolveCore(JobPersonnel source)
{
var totalDays = CalculateDaysBetween(source.LeaveOffice.GetValueOrDefault(), source.ReturnOffice.GetValueOrDefault());
return totalDays;
}
private double CalculateDaysBetween(DateTime d1, DateTime d2)
{
if (d1 >= DateTime.Now || d1 == DateTime.MinValue) return 0;
d2 = SetTimeNowIfDateOutIsMinValue(d2);
var span = d2.Subtract(d1);
var totalDays = span.TotalDays.ToString("F2");
return Double.Parse(totalDays);
}
private DateTime SetTimeNowIfDateOutIsMinValue(DateTime d2)
{
if (d2 == DateTime.MinValue)
d2 = DateTime.Now;
return d2;
}
}
ViewModel
public class PersonnelVM
{
public int Refno { get; set; }
public int JobID { get; set; }}
[UIHint("StartDate")]
public DateTime? LeaveOffice { get; set; }
[UIHint("EndDate")]
public DateTime? ReturnOffice { get; set; }
public double TotalDays { get; set; }
}
Mapping
CreateMap<PersonnelVM, JobPersonnel>()
.ReverseMap()
.ForMember(dst => dst.TotalDays, opt => opt.ResolveUsing<TotalDaysResolver>()));
Query
public IEnumerable<PersonnelVM> GetAllPersonnelByJobId(int jobid)
{
return _dbRepository.GetWhere<PersonnelVM, JobPersonnel>(w => w.JobID == jobid); //This is where I get the error
}
The mapping doesn't throw any errors if I comment out the map for TotalDays. Unfortunately I can't find any information online to point me in any direction of solving this issue. I'm new to programming and newer to automapper.
Does anyone have insight into this error and/or how I can go about debugging this issue myself?
Upvotes: 1
Views: 1871
Reputation: 48454
The ResolveUsing
is not allowed in projection operations against EF (Entities). You mentioned that you moved the mapping logic into the view model, but you could also have abandoned your custom resolver and provided Parameters for your MapFrom
(albeit complicated in your specific case) - see https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions
Assuming your TotalDays
property... now looks something like:
[IgnoreMap]
public double TotalDays => CalculateDaysBetween(this.LeaveOffice, this.ReturnOffice)
Which is similar to the approach I sometimes take with conditional/computational properties. I populate "helper" properties from the DB and then rely on the getter to finish the Resolve.
Unfortunately this is the best we can get at present (see https://github.com/AutoMapper/AutoMapper/issues/415) as AutoMapper has to hand off the expression tree to the EF query engine and loses context of those operations.
Upvotes: 2