简体   繁体   中英

How to properly define AutoMapper config for complex class?

I'm working with Entity Framework, and getting ready to redo a project that is currently using EF->BDO->DTO->client with manual conversions for each class along the way.

I came across AutoMapper and think this would be a better solution overall. I have had no issues mapping CustomerEF -> CustomerDto, OfficeEF -> OfficeDto, etc, but I am now working on a more complex class, and struggling to get everything in place.

I feel I am close, and that something has to happen in reverse, but have not been able to identify what I'm missing.

    public class CaseDto
{
    public int CaseId { get; set; }
    public string CaseReason { get; set; }
    public CustomersDto _customer { get; set; }
    public OfficeDto _office { get; set; }
    public CaseNotesDto[] _caseNotes { get; set; }
}

public class CustomersDto
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
}

public class OfficeDto
{
    public int OfficeId { get; set; }
    public string OfficeName { get; set; }
}

public class CaseNotesDto
{
    public int CaseNotesId { get; set; }
    public int CaseId { get; set; }
    public string CaseNote { get; set; }
}

// EF objects

public class CaseEF
{
    public int CaseId { get; set; }
    public string CaseReason { get; set; }
    public int CustomerId { get; set; }
    public int OfficeId { get; set; }
}

public class CustomerEF
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
}

public class OfficeEF
{
    public int OfficeId { get; set; }
    public string OfficeName { get; set; }
}

public class CaseNotesEF
{
    public int CaseNotesId { get; set; }
    public int CaseId { get; set; }
    public string CaseNote { get; set; }
}

// execution classes

public class CaseFramework
{
    // set 'ef' variables
    private readonly OfficeEF _officeEf = new OfficeEF { OfficeId = 1, OfficeName = "Washington" };
    private readonly CustomerEF _customerEf = new CustomerEF { CustomerId = 1, CustomerName = "Blips and Chitz" };

    private readonly CaseNotesEF[] _caseNotesEf = 
    {
        new CaseNotesEF {CaseNotesId = 1, CaseNote = "Case 1", CaseId = 1000},
        new CaseNotesEF {CaseNotesId = 2, CaseNote = "Case 2", CaseId = 1000}
    };

    private readonly CaseEF _case =
        new CaseEF { CaseId = 1000, CaseReason = "Roy is back!", CustomerId = 1, OfficeId = 1 };

    public CaseDto GetCase(int caseId)
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<OfficeEF, OfficeDto>();
            cfg.CreateMap<CustomerEF, CustomersDto>();
            cfg.CreateMap<CaseNotesEF, CaseNotesDto>();
            cfg.CreateMap<CaseEF, CaseDto>()
                .ForMember(dest => dest._customer, opt => opt.MapFrom(src => src.CustomerId))
                .ForMember(dest => dest._office, opt => opt.MapFrom(src => src.OfficeId))
                .ForMember(dest => dest._caseNotes,
                    opt => opt.MapFrom(src => _caseNotesEf.Where(x => x.CaseId == caseId)));
        });

        Mapper.AssertConfigurationIsValid();

        var source = new CaseEF { CaseId = caseId };
        var destination = Mapper.Map<CaseEF, CaseDto>(source);


        return destination;
    }
}

To run this I am doing:

var b = new CaseFramework();
var result = b.GetCase(1000);

The results are populating the CaseId (set manually) and the CaseNotesDto, but nothing else.

Having the first 3 cfg.CreateMap items in the Mapper.Initialize section makes no difference if they are there or not.

Thanks in advance for any guidance.

Appreciate the responses.

@MickyD, I was a little confused on the POCO comment, as the EF already generated a tt, and the Canonical schema/model looks like something I'll have to research more.

@Steve I checked my navigation properties from my EF database and we need to do some fixes to the relationships before making the Include method work, but I think that will ultimately be the solution. In the meantime I was able to accomplish the original goal with this:

            Mapper.AssertConfigurationIsValid();

            var destination = Mapper.Map<CaseDto>(_case);
            destination.Customers = Mapper.Map<CustomerEF, CustomersDto>(_customerEf);
            destination.Office = Mapper.Map<OfficeEF, OfficeDto>(_officeEf);

            return destination;

Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM