我正试图在automapper中使用一个自定义值解析程序来获取运行时两个日期之间的差异。
解析器
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; }
}
映射
CreateMap<PersonnelVM, JobPersonnel>()
.ReverseMap()
.ForMember(dst => dst.TotalDays, opt => opt.ResolveUsing<TotalDaysResolver>()));
查询
public IEnumerable<PersonnelVM> GetAllPersonnelByJobId(int jobid)
{
return _dbRepository.GetWhere<PersonnelVM, JobPersonnel>(w => w.JobID == jobid); //This is where I get the error
}
如果我为TotalDays注释掉映射,映射不会抛出任何错误。不幸的是,我在网上找不到任何信息来指引我解决这个问题的方向。我是编程新手,也是自动映射器新手。
有人了解这个错误吗?和/或我如何自己调试这个问题?
在针对EF(实体)的投影操作中不允许使用ResolveUsing
。您提到将映射逻辑移动到视图模型中,但也可以放弃自定义解析器,为MapFrom
提供Parameters(尽管在特定情况下很复杂)-请参阅https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions
假设您的TotalDays
属性。。。现在看起来像:
[IgnoreMap]
public double TotalDays => CalculateDaysBetween(this.LeaveOffice, this.ReturnOffice)
这与我有时使用条件/计算属性的方法类似。我从DB中填充"helper"属性,然后依靠getter来完成Resolve。
不幸的是,这是我们目前能得到的最好的(请参阅https://github.com/AutoMapper/AutoMapper/issues/415)因为AutoMapper必须将表达式树交给EF查询引擎并丢失这些操作的上下文。