user3738893
user3738893

Reputation: 435

Automapper System.Exception "Can't resolve this to Queryable Expression"

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

Answers (1)

Brett Veenstra
Brett Veenstra

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

Related Questions