简体   繁体   中英

Map property to property of a collection automapper

I have two entities

public class A{
    public string Example { get; set; }
    public ICollection<B> BCollection { get;set; } = new HashSet<B>();
}

public class B {
    public string MyProperty { get; set; }
}

And a simple ViewModel

public class AFirstLoadViewModel {
    public string Example { get; set; }
    public string MyProperty { get; set; }
}

The thing, is, this viewmodel will be use only in the first data entry, when A will only have one B object inside.

So, i'm trying to map a object like this:

var source = new AFirstLoadViewModel
{
    Example = "example",
    MyProperty = "myproperty"
}

to this

var destination = new A {
    Example = "example"
    BCollection = new List<B> {
        new B { MyProperty = "myproperty" }
    }
}

I try to do the trick using ForPath and BeforeMap without luck

CreateMap<AFirstLoadViewModel, A>()
    .ForMember(x => x.Example, c => c.MapFrom(x => x.Example))
    .ForPath(x => x.BCollection.First().MyProperty, c => c.MapFrom(x => x.MyProperty))
    .BeforeMap((viewModel, entity) => {
        if(!entity.BCollection.Any())
            BCollection.Add(new B());
    });

But i get

System.ArgumentOutOfRangeException: Only member accesses are allowed.

How can i deal with it?

I clarify: both, view model and model have many more properties, the question classes are by way of example

Edit:


I try the solution proposed by Johnatan, and it works, the problem here, is that i cant Unit Testing anymore.

I'm testing with

var config = new MapperConfiguration(cfg => cfg.CreateMap<AFirstLoadViewModel, A>(MemberList.Source));

And when i call config.AssertConfigurationIsValid() fails because the MyProperty property is not mapped

The problem is you are trying to map to .First(). First does not yet exist because the query is on a null / empty collection. You can't assign to the .First() element in a collection if one does not exist already. Instead just map as a collection directly.

CreateMap<AFirstLoadViewModel, A>()
.ForMember(x => x.Example, c => c.MapFrom(x => x.Example))
.ForMember(x => x.BCollection, c => c.MapFrom(x => new [] { new B { MyProperty = x.MyProperty } }));
CreateMap<AFirstLoadViewModel, A>()
    .ForMember(x => x.Example, c => c.MapFrom(x => x.Example))
    .ForMember(x => x.BCollection, c => c.MapFrom(x => new [] { new B { MyProperty = x.MyProperty } })); 

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