AutoMapper / AutoMapper.Collection.EFCore

EFCore support for AutoMapper.Collections

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing type map configuration or unsupported mapping

cursorme opened this issue · comments

Hi,

I'm getting this error:

"AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
PipetteModelDto -> Expression1 PipetteModels.PipetteModelDto -> System.Linq.Expressions.Expression1[[System.Func`2[[VolumetricsDomain.PipetteModel, VolumetricsDomain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, ..."

Seems that when tring to make:
await _context.PipetteModels.Persist (_mapper).InsertOrUpdateAsync(PipetteModelDto);

Is expecting a map to a expression and not something line I have rigth now:
CreateMap<PipetteModel, PipetteModelDto> ()
...
.ReverseMap ();

On startup I have:
services.AddAutoMapper ((serviceProvider, automapper) => {
automapper.AddProfile(new MappingProfile());
automapper.AddCollectionMappers ();
automapper.UseEntityFrameworkCoreModel (serviceProvider); automapper.SetGeneratePropertyMaps<GenerateEntityFrameworkCorePrimaryKeyPropertyMaps>();
}, typeof (DataContext).Assembly);

What would be the correct mapping to use from a dto to a EF Core class ?

Thanks
Eduardo

Start with removing the automapper.SetGeneratePropertyMaps<GenerateEntityFrameworkCorePrimaryKeyPropertyMaps>(); line, it should not be there, the UseEntityFrameworkCoreModel<> will set the correct property maps up for you.

Please, provide more information about your model and dto's and if possible small complete example that will cause this exception.

Hi,

Removing that line the error is exacly the same.I've use it because I've found it here as alternative to use EqualityComparison for each entity.... I'm a lazy guy :)
I will try to gather a more complete sample to show it but seems that could be related to this ?
"Note: This is done by converting the OrderDTO to Expression<Func<Order,bool>> and using that to find matching type in the database."

"Normal" automapper Map works fine. For example the first line works properly while the commented one does not throwing that error:
var test = _mapper.Map<PipetteModelDto, PipetteModel> (request.PipetteModel);
//await _context.PipetteModels.Persist (_mapper).InsertOrUpdateAsync(request.PipetteModel);

I'm using .Net Core 3.1 + EF Core + Npgsql 3.1 + Automapper 9.0
I've just open is issue to see if I was missing something pretty obvious or not....

Thanks
Eduardo

I am facing the same error.

@rdkashmir Please, provide more information about your model and dto's and if possible small complete example that will cause this exception.

I get this error when I pass a db entity rather than a dto to InsertOrUpdate().
A very disappointing limitation.

commented

I fixed this issue by not using AutoMapper.Collections.EntityFrameworkCore and adding a few rules to mapper profile.

CreateMap<Category, CategoryDto>()
    .EqualityComparison((a, b) => a.Id == b.Id);

CreateMap<CategoryDto, Category>()
    // REQUIRED to ignore primary keys
    .ForMember(x => x.Id, x => x.Ignore())
    .EqualityComparison((a, b) => a.Id == b.Id);

CreateMap<CategoryTranslation, CategoryTranslationDto>()
    .EqualityComparison((a, b) => a.LanguageId == b.LanguageId);

CreateMap<CategoryTranslationDto, CategoryTranslation>()
    .EqualityComparison((a, b) => a.LanguageId == b.LanguageId);

Instead of Collections.EFCore you could write something like that:

// Received from request body ([FromBody] CategoryDto doc)
CategoryDto dto;

// Update data
Category model = await _context.Categories
    .Include(c => c.Translations)
    .SingleOrDefaultAsync(c => c.Id == id);

if (model == null) {
    return NotFound();
}

_mapper.Map(dto, model);
await _context.SaveChangesAsync();

// Add new entry
Category model = _mapper.Map<Category>(dto);

_context.Categories.Add(model);
await _context.SaveChangesAsync();

I know it's not same thing as InsertOrUpdate but I think most of the times we need to just insert or update data.

me too , but yes .Persist(mapper).InsertOrUpdateAsync(parms); @### ### ::><::

I have same problem for remove data.
await _context.AppUser.Persist(mapper).RemoveAsync(result);

WebAPI code

    public async Task<IActionResult> UpdateUser(AppUserDTO model)
    {
        try
        {

            var data = await _context.AppUser.Include(c => c.Logs).AsNoTracking().SingleOrDefaultAsync(c => c.Id == model.Id);

            if (data == null)
                return NotFound();

            var mapper = new MapperConfiguration(cfg =>
            {
                cfg.AddCollectionMappers();
                cfg.CreateMap<AppUserDTO, AppUser>()
                .EqualityComparison((odto, o) => odto.Id == o.Id);

                cfg.CreateMap<LogDTO, Log>()
                .EqualityComparison((odto, o) => odto.Id == o.Id);

            }).CreateMapper();
            var result = mapper.Map<AppUserDTO, AppUser>(model, data);

            await _context.AppUser.Persist(mapper).InsertOrUpdateAsync(model);

            //Remark it and worked
            await _context.AppUser.Persist(mapper).RemoveAsync(result);

            data = await _context.AppUser.Include(c => c.Logs)
                .AsNoTracking()
               .SingleOrDefaultAsync(c => c.Id == model.Id);

            return Ok(data);
        }
        catch (Exception ex)
        {

            return BadRequest(ex.InnerException == null ? ex.Message : ex.InnerException.Message);
        }
    }

public class AppUser : IdentityUser<int>
{
    public List<Log> Logs { get; set; }
}

public class Log
{
    public int AppUserId { get; set; }
    public int Id { get; set; }
    public string Msg { get; set; }
}

public class AppUserDTO
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public List<Log> Logs { get; set; }
}

public class LogDTO : Log
{
}

Error message:

**Missing type map configuration or unsupported mapping.

Mapping types:
AppUser -> Expression1
AutoMapperForEFcore.Models.AppUser -> System.Linq.Expressions.Expression`1[[System.Func2[[AutoMapperForEFcore.Models.AppUser, AutoMapperForEFcore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]**

AutoMapper 9.0.0
AutoMapper.Collection 6.0.0
AutoMapper.Collection.EntityFrameworkCore 1.0.1

@felaray you are not initiating this package in the mapping configuration. See configuration example in the readme.

The '**Missing type map configuration or unsupported mapping.' Is from automapper that changed a default settings, see their breaking changes.

It's my mistake, the problem has been solved , thanks!

var user =_userRepository.GetUserByUsernameAsync(username);
if (user is null) return NotFound();
_ = _mapper.Map(memberUpdateDto, user);

I've also faced the same issue. After a while I realize that I forget to use await when query into database.
When I fix it ,

var user = await _userRepository.GetUserByUsernameAsync(username);

Then, It works fine.

Thank you, It works for me @MehrajShakil