I have the following Entity Framework Entities:
public class Region { public int RegionId { get; set; } // Primary Key public string Name { get; set; } public virtual ICollection<Country> Countries { get; set; } // Link Table } public class Country { public int CountryId { get; set; } // Primary Key public string Name { get; set; } public int RegionId { get; set; } // Foreign Key }
I map them using AutoMapper for the following ViewModels:
public class RegionViewModel { public int RegionId { get; set; } public string Name { get; set; } public virtual ICollection<int> Countries { get; set; } } public class CountryViewModel { public int CountryId { get; set; } public string Name { get; set; } }
I want to transfer my ViewModels to objects using AutoMapper to save a new region. This is my display code:
Mapper.CreateMap<RegionViewModel, Region>() .ForMember(x => x.Countries, x => x.MapFrom(y => y.Countries.Select(z => new Country() { CountryId = z }).ToArray()));
This throws an exception when adding a region to the repository, as it also tries to create a new instance of the country with a null name. One solution is to change the Add method in my repository to set the state of country objects in Unchanged.
public async Task Add(Region region) { foreach (Country country in region.Countries) { this.Context.Entry(country).State = EntityState.Unchanged; } await base.Add(region); }
Another alternative solution is to use a more complex translation logic, which uses a different repository to get objects from a real country. This approach has lower performance because it should make an extra call to the database, but you will also get a more complete Region object.
Mapper.CreateMap<RegionViewModel, Region>(); Mapper.CreateMap<int[], Country[]>().ConvertUsing(x => countryRepository.GetAll().Result.Where(y => x.Contains(y.CountryId)).ToArray());
I lean toward the first, but what's the right approach?