1

I'm stuck trying to map ViewModel class using Automapper with classes listed below:

public class Product
{
    [Key]
    public int ProductId { get; set; }
    public string Name { get; set; }
    public ICollection<Color> Color { get; set; }
}

public class Color
{
    [Key]
    public int id { get; set; }
    public string value { get; set; }

    public virtual ICollection<Product> products { get; set; }
}

public class ProductVM
{
    [Key]
    public int ProductId { get; set; }
    public string Name { get; set; }
    public List<int> Color { get; set; }
    public IEnumerable<Color> Colors { get; set; } 
}

With Colors I pass all the available colors to the View for user to choose, and Color property to get the values, having something like this into the view:

@Html.ListBoxFor(model => Model.Color, new MultiSelectList(Model.Colors, "id", "value"));

Then in a contorller I've got a Post method, which saves it. I tryed to use Automapper to convert classes but it fails to map Color property as it should get the Color object by the available id.

Mapper.CreateMap<ProductVM, Product>();
Product product = AutoMapper.Mapper.Map<ProductVM, Product>(productVM);
db.Products.Add(product);
db.SaveChanges();

Am I missing somethig?

hitry
  • 25
  • 4

2 Answers2

1

I tried something in my solution, colors will be null as the selectlist is not returned from the view. Your list of int's (color) will not be null and you can map this to the color object.

var productVM = new ProductVM
{
    Name = "Test",
    ProductId = 5,
    Colors = null,
    Color = new List<int> {1, 5, 8}
};

Mapper.CreateMap<int, Color>()
    .ForMember(dest => dest.id, opt => opt.MapFrom(src => src));

Mapper.CreateMap<ProductVM, Product>()
    .ForMember(dest => dest.Color, opt => opt.MapFrom(src => src.Color));

Product product = AutoMapper.Mapper.Map<ProductVM, Product>(productVM);
db.Products.Add(product);
db.SaveChanges();
Jelle Oosterbosch
  • 1,731
  • 15
  • 17
  • It's almost work as it should, but somehow I get new additional records in a Color table, ie if I pass 2 color ids I get 2 new Colors (which values are null) and a product connected with them but not with original ones. – hitry Aug 03 '15 at 05:54
  • I just read your comment, did you get the Color objects also mapped? – Jelle Oosterbosch Aug 04 '15 at 07:57
  • Yes, I have them mapped. Before transaction they are included into Product oject with proper ids and null values but after transaction I get new records in a Color table. – hitry Aug 05 '15 at 05:49
0

This is happening because Automapper doesn't know how to map from List< int > Color to ICollection< Color > Colors. Try creating a map for this also.

Mapper.CreateMap<SourceObject, TargetObject>();
Mapper.CreateMap<SourceOuterObject, TargetOuterObject>()
    .ForMember(dest => dest.TargetList, opt => opt.MapFrom(src => src.SourceSet.SourceList);
sarin
  • 5,227
  • 3
  • 34
  • 63
  • That would need to be map from `List Color` to `ICollection Color` (`IEnumerable Colors` will be an empty list in the POST method) –  Jul 31 '15 at 12:00
  • Agree. I wasn't sure though as, why would you want to map an int to a color object?... Wasn't sure if it was a typo. hopefully the OP will understand what i am suggesting – sarin Jul 31 '15 at 12:03
  • OP need to map `List` to `ICollection Color` because property `Color` is the property the ListBox is being bound to and it will contain a collection of the color `ID` in the POST method –  Jul 31 '15 at 12:07
  • In which case there should also be a mapping from int to color ? – sarin Jul 31 '15 at 12:12
  • Yes, there should be mapping from int to color, I've managed to do this with custom type converter but it calls the context inside and I feel that I'm doing it wrong. – hitry Aug 03 '15 at 05:59