There are some classes with relations for me
public class MasterList
{
public int ListId { get; set; }
public string ListName { get; set; }
public int CompanyId { get; set; }
public string Company { get; set; }
public int UniqueId { get; set; }
public DateTime Created { get; set; }
public List<MasterSubList> SubLists { get; set; }
}
public class MasterSubList
{
public int SubListId { get; set; }
public string SubListName { get; set; }
public string Status { get; set; }
public DateTime Created { get; set; }
public List<SubListClick> Clicks { get; set; }
}
public class SubListClick
{
public int ClickId { get; set; }
public string ClickName { get; set; }
}
Can we create a SubList ViewModel by copying all properties from associated MasterList for each of the MasterSubList using AutoMapper?
public class SubListViewModel
{
public int ListId { get; set; }
public string ListName { get; set; }
public int CompanyId { get; set; }
public string Company { get; set; }
public int UniqueId { get; set; }
public DateTime Created { get; set; }
public int SubListId { get; set; }
public string SubListName { get; set; }
public string Status { get; set; }
public DateTime Created { get; set; }
public List<SubListClick> Clicks { get; set; }
}
if my MasterList contain 2 items with 2 MasterSubList each , My resulting SubListViewModel should contain 4 items in total
Can we define automapper mapping against the SubListViewModel based on MasterSubList but include properties from parent MasterList
public class SubListViewModel: IMapFrom<MasterSubList>
{
public int ListId { get; set; }
public string ListName { get; set; }
public int CompanyId { get; set; }
public string Company { get; set; }
public int UniqueId { get; set; }
public DateTime ListCreated { get; set; }
public int SubListId { get; set; }
public string SubListName { get; set; }
public string Status { get; set; }
public DateTime Created { get; set; }
public List<SubListClick> Clicks { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<EcastCampaign, ECastRecordsModel>()
.ForMember(d => d.ListId, opt => opt.MapFrom(p => p. ????????? )) how to access Parent object here
.ForMember(d => d.ListName, opt => opt.MapFrom(p => p.?????????))
.ForMember(d => d.CompanyId, opt => opt.MapFrom(p => p.?????????))
.ForMember(d => d.Company, opt => opt.MapFrom(p => p.?????????))
.ForMember(d => d.UniqueId, opt => opt.MapFrom(p => p.))
.ForMember(d => d.ListCreated, opt => opt.MapFrom(p => p.?????????))
}
}
or the mapping should be at some other way?
At present I am doing this conversion by looping through the list
List<SubListViewModel> eRecords = new List<SubListViewModel>();
foreach (MasterList list in apiData)
{
foreach (MasterSubList campign in list.SubLists)
{
SubListViewModel _record = new SubListViewModel();
_record.SubListId = campign.SubListId ;
_record.SubListName = campign.SubListName ;
_record.Status = campign.Status;
_record.CampaignCreated = campign.Created;
_record.Clicks= campign.Clicks;
// now populate parent properties
_record.ListId = list.ListId;
_record.ListName = list.ListName;
_record.CompanyId = list.CompanyId;
_record.Company = list.Company;
_record.UniqueId = list.UniqueId;
_record.ListCreated = list.Created;
eRecords.Add(_record);
}
}
Related
I try to use AutoMapper but when I what to map 2 collection I get an error.
These are my entity and dto classes that I want to use AutoMapper:
public class HeadQuarters
{
public int Id { get; private set; }
public string HeadQuartersName { get; set; }
public string HeadQuartersCode { get; set; }
public string HeadQuartersDescription { get; set; }
public bool IsActiv { get; set; }
public ICollection<Adresa> Adresa { get; set; }
}
public class HeadQuartersDTO
{
public string HeadQuartersName { get; set; }
public string HeadQuartersCode { get; set; }
public string HeadQuartersDescription { get; set; }
public ICollection<AdresaDTO> Addresses { get; set; }
public EntityState Status { get; set; }
}
These are my entity and dto collection classes:
public class AdresaDTO
{
public int Id { get; set; }
public string Street { get; set; }
public string StreetNr { get; set; }
public string Block { get; set; }
public string Entrance{ get; set; }
public string Apartment{ get; set; }
public double? Longitude { get; set; }
public double? Latitude { get; set; }
public int? CityId { get; set; }
public EntityState Status { get; set; }
}
public partial class Adresa
{
public int Id { get; private set; }
public string Street { get; set; }
public string StreetNr { get; set; }
public string Block { get; set; }
public string Entrance{ get; set; }
public string Apartment{ get; set; }
public double? Longitude { get; set; }
public double? Latitude { get; set; }
public int CityId { get; set; }
public int? HeadQuartersId { get; set; }
public int? EmployeeId { get; set; }
public int? ContractPersonDataId { get; set; }
}
I write this code for to use AutoMapper:
public static HeadQuarters DtoToEntity(HeadQuartersDTO dto)
{
var mapper = new Mapper(MapperConfiguration());
return mapper.Map<HeadQuarters>(dto);
}
private static MapperConfiguration MapperConfiguration()
{
return new MapperConfiguration(cfg =>
cfg.CreateMap<HeadQuartersDTO, HeadQuarters>()
.ForMember(dest => dest.Adresa, act => act.MapFrom(src => src.Addresses)));
}
But when I add some in collection I get an error. This is the error message that I get:
If I understand what you’re trying to do, you should be able to update your code like this:
public static HeadQuarters DtoToEntity(HeadQuartersDTO dto)
{
var mapper = new Mapper(MapperConfiguration());
return mapper.Map<HeadQuarters>(dto);
}
private static MapperConfiguration MapperConfiguration()
{
return new MapperConfiguration(cfg =>
cfg.CreateMap<AdresaDTO, Adresa>()
.ForMember(dest => dest.CityId, act => act.MapFrom(src => src.CityId ?? default(int)))
.ForMember(dest => dest.HeadQuartersId, act => act.Ignore())
.ForMember(dest => dest.EmployeeId, act => act.Ignore())
.ForMember(dest => dest.ContractPersonDataId, act => act.Ignore());
cfg.CreateMap<HeadQuartersDTO, HeadQuarters>()
.ForMember(dest => dest.Id, act => act.Ignore())
.ForMember(dest => dest.IsActiv, act => act.Ignore())
.ForMember(dest => dest.Adresa, act => act.MapFrom(src => src.Addresses)));
}
Issue with a particular type of mapping with classes SourceClass and DestinationClass
public class SourceClass
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<SourceNestedClass> SourceNestedClasses { get; set; }
}
public class SourceNestedClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class DestNestedClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
}
public class DestinationClass
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<DestNestedClass> Nesteds { get; set; }
}
public DestinationClass MapAutomatically(SourceClass source)
{
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.Nesteds, opt => opt.Ignore())
.AfterMap((src, dest) =>
{
dest.Nesteds.Clear();
foreach (var nested in src.SourceNestedClasses )
{
DestNestedClass destNest=new DestNestedClass();
destNest.Id=nested.Id;
destNest.FirstName=nested.FirstName;
destNest.LastName=nested.LastName;
destNest.FullName=nested.FullName;
dest.Nesteds.Add(destNest);
}
});
return Mapper.Map<DestinationClass>(source);
}
Want to avoid manual mapping option in MapAutomatically. In this process need to map each properties.To avoid manual mapping is there any process to use bellow syntax.
Mapper.CreateMap<SourceNestedClass, DestNestedClass>()
.ForMember(dest => dest.FullName, opt => opt.FirstName+opt.LastName);
The syntax is descriptive, for nested class mapping with automapper need to take care parent class and child classes as like following
- mapping parent classes with nested classes
- mapping classes
public class SourceClass
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<SourceNestedClass> SourceNestedClasses { get; set; }
public SourceClass()
{
SourceNestedClasses = new List<SourceNestedClass>();
}
}
public class SourceNestedClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class DestNestedClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
}
public class DestinationClass
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<DestNestedClass> Nesteds { get; set; }
public DestinationClass()
{
Nesteds = new List<DestNestedClass>();
}
}
class Program
{
public static DestinationClass MapAutomatically(SourceClass sourceInfo)
{
var config = new MapperConfiguration(cfg =>
{
//mapping parent classes with nested classes
cfg.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.Nesteds, opt => opt.MapFrom(source => source.SourceNestedClasses));
//mapping classes
cfg.CreateMap<SourceNestedClass, DestNestedClass>()
.ForMember(dest => dest.FullName, opt => opt.MapFrom(source => source.FirstName + source.LastName));
});
var mapper = config.CreateMapper();
var destResult = mapper.Map<SourceClass, DestinationClass>(sourceInfo);
return destResult;
}
static void Main(string[] args)
{
var sourceInfo = new SourceClass
{
Id = 5,
Name = "SourceClass",
SourceNestedClasses = { new SourceNestedClass { Id = 10, FirstName = "Test", LastName = "Address" } }
};
var destResult = MapAutomatically(sourceInfo);
}
}
}
I have a db objects that i would like to map to my view object in my application, but not every property getting mapped.
here is my Automapper set up:
Here is my View class that i would like AutoMapper to map to
public class CustomerDetails
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Dob { get; set; }
public DateTime CreateDate { get; set; }
public decimal Balance { get; set; }
public List<Email> Emails { get; set; }
public List<Address> Addresses { get; set; }
public class Email
{
public Guid Id { get; set; }
public string EmailName { get; set; }
}
public class Address
{
public Guid Id { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
}
}
Here is db classes:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual CustomerBalance Balance { get; set; }
public virtual ICollection<Email> Emails { get; set; }
public virtual ICollection<Address> Address { get; set; }
public class Email
{
public Guid Id { get; set; }
public string EmailName { get; set; }
public bool IsPrimary { get; set; }
public virtual Customer Customer { get; set; }
}
public class Address
{
public Guid Id { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
}
}
here is how i set up my configuration for AutoMapper
Mapper.Initialize(config =>
{
config.AddProfile<CustomerProfile>();
});
public class CustomerProfile : Profile
{
public CustomerProfile()
{
CreateMap<DataModels.Phone, Phone>();
CreateMap<DataModels.Email, Email>();
CreateMap<DataModels.Address, Address>();
CreateMap<DataModels.CustomerPin, Pin>()
.ForMember(x => x.PinNumber, y => y.MapFrom(s => s.Pin))
.ForMember(x => x.Id, y => y.MapFrom(s => s.Id))
;
CreateMap<Customer, CustomerDetails>()
.ForMember(x => x.Phones, y => y.MapFrom(s => s.Phones))
.ForMember(x => x.Emails, y => y.MapFrom(s => s.Emails))
.ForMember(x => x.Balance, y => y.MapFrom(s => s.Balance.Balance))
.ForMember(x => x.Pins, y => y.MapFrom(s => s.Pin))
.ForMember(x => x.Addresses, y => y.MapFrom(s => s.Address))
;
CreateMap<Customer, CustomerDetails>().ReverseMap();
}
}
The strange thing is is that everything getting mapped as expected, except the Addressesproperty and Balance on my CustomerDetails.cs. The list collection is null even though i specified to map it from a member. However, email List is getting mapped appropriately.
Am I missing something?
I have the following domain model (one class):
public class DriverDomain
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int? TruckId { get; set; }
public int? TrailerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? UnitNo { get; set; }
public int? GpsId { get; set; }
public string CompanyFEIN { get; set; }
public string CompanyName { get; set; }
public string CompanyAddress { get; set; }
public string CompanyCity { get; set; }
public string CompanyZIP { get; set; }
public string CompanyState { get; set; }
public System.DateTime? DOB { get; set; }
public string SSN { get; set; }
public string PhoneNo { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZIP { get; set; }
public string DLno { get; set; }
public string Dlstate { get; set; }
public System.DateTime? DLexp { get; set; }
public System.DateTime? MedExp { get; set; }
public System.DateTime? HireDate { get; set; }
public System.DateTime? TermDate { get; set; }
public bool Active { get; set; }
public bool DrugTest { get; set; }
public string Notes { get; set; }
public string CardNo { get; set; }
public string EmployeeNo { get; set; }
public bool? OwnerOp { get; set; }
public bool OccAcc { get; set; }
public decimal? WeeklyOccAcc { get; set; }
public bool Ifta { get; set; }
public decimal? WeeklyIfta { get; set; }
public bool TrailerRental { get; set; }
public decimal? WeeklyTrailerRent { get; set; }
public bool CargoIns { get; set; }
public decimal? WeeklyCargoIns { get; set; }
public decimal? PilotRebate { get; set; }
public bool OnlineAccess { get; set; }
public int? OnlineId { get; set; }
public bool ViewedSchedule { get; set; }
public int SchedulePriority { get; set; }
public bool Hourly { get; set; }
public decimal? HourlyPay { get; set; }
public string IpassTransponderId { get; set; }
public System.DateTime? RecordDate { get; set; }
public string RecordChangedBy { get; set; }
public string EmgcontactName { get; set; }
public string EmgcontactPhone { get; set; }
public string EmgcontactRelationship { get; set; }
public string Nickname { get; set; }
public string UserId { get; set; }
public string AspNetUserName { get; set; }
public string AvatarUrl { get; set; }
public bool PaidByPercent { get; set; }
public decimal? PercentPaid { get; set; }
public bool PaidByMile { get; set; }
public decimal? PayPerMile { get; set; }
public bool CompanyPlates { get; set; }
public decimal? WeeklyPlateCharge { get; set; }
public bool EnableEscrowDeductionOnPayroll { get; set; }
public decimal WeeklyEscrowDeduction { get; set; }
public bool ShowPersonalConveyance { get; set; } = false;
public bool ShowYardMoves { get; set; } = false;
public string StartTimeOfDay { get; set; } = "00:00:00.000";
}
and many view model classes, each of them can be mapped to this domain class:
public class DriverPersonalInfoVM
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public System.DateTime? DOB { get; set; }
public string SSN { get; set; }
public string PhoneNo { get; set; }
...
public class DriverEmploymentVM
{
public int Id { get; set; }
public System.DateTime? HireDate { get; set; }
public System.DateTime? TermDate { get; set; }
public bool DrugTest { get; set; }
public bool OnlineAccess { get; set; }
public bool ViewedSchedule { get; set; }
map rules:
CreateMap<Domain.POCO.Driver.DriverDomain, DriverPersonalInfoVM>();
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEmploymentVM>();
CreateMap<Domain.POCO.Driver.DriverDomain, DriverPayrollVM>();
CreateMap<Domain.POCO.Driver.DriverDomain, DriverCompensationVM>();
CreateMap<Domain.POCO.Driver.DriverDomain, DriverFuelTollsVM>();
CreateMap<Domain.POCO.Driver.DriverDomain, DriverAvatarVM>();
it works fine.
But now I have the following view model class:
public class DriverEditVM
{
public DriverEditVM(int id)
{
Id = id;
PersonalInfo = new DriverPersonalInfoVM { Id = id };
Employment = new DriverEmploymentVM { Id = id };
Payroll = new DriverPayrollVM { Id = id };
Compensation = new DriverCompensationVM { Id = id };
FuelTolls = new DriverFuelTollsVM { Id = id };
Avatar = new DriverAvatarVM { Id = id };
}
public DriverPersonalInfoVM PersonalInfo { get; set; }
public DriverEmploymentVM Employment { get; set; }
public DriverPayrollVM Payroll { get; set; }
public DriverCompensationVM Compensation { get; set; }
public DriverFuelTollsVM FuelTolls { get; set; }
public DriverAvatarVM Avatar { get; set; }
}
and map rule:
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEditVM>();
but when I try to map domain object to DriverEditVM:
var driver = _driverService.GetDriver(id.Value);
DriverEditVM model = mapper.Map<DriverEditVM>(driver);
I have empty properties PersonalInfo, Employment etc. How to map it?
As you have created maps for all your other view models that form part of your DriverEditVM, you should be able to do this:
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEditVM>()
.ForAllMembers(opt => opt.MapFrom(src => src));
Edit
As some members are not being mapped, there are two approaches, explicitly ignore the un-mapped members or explicitly map the mapped members:
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEditVM>()
.ForMember(dest => dest.IgnoredProperty1, opt => opt.Ignore())
.ForMember(dest => dest.IgnoredProperty2, opt => opt.Ignore())
.ForAllOtherMembers(opt => opt.MapFrom(src => src));
Or
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEditVM>()
.ForMember(dest => dest.PersonalInfo, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Employment, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Payroll, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Compensation, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.FuelTolls, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Avatar, opt => opt.MapFrom(src => src))
.ForAllOtherMembers(opt => opt.Ignore());
Solved this problem :
CreateMap<Domain.POCO.Driver.DriverDomain, DriverEditVM>()
.ForMember(p => p.PersonalInfo, p => p.MapFrom(src => src))
.ForMember(p => p.Avatar, p => p.MapFrom(src => src))
.ForMember(p => p.Compensation, p => p.MapFrom(src => src))
.ForMember(p => p.Employment, p => p.MapFrom(src => src))
.ForMember(p => p.FuelTolls, p => p.MapFrom(src => src))
.ForMember(p => p.Payroll, p => p.MapFrom(src => src))
;
I want to map one call to another, but I got exception all the time /An exception of type 'AutoMapper.AutoMapperMappingException' occurred in AutoMapper.dll but was not handled in user code/
Here are my Source Classes:
public class Snippet
{
public Snippet()
{
this.Labels = new HashSet<Label>();
this.Commennts = new HashSet<Comment>();
}
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Description { get; set; }
[Required]
public string Code { get; set; }
public int LanguageId { get; set; }
public string UserId { get; set; }
public DateTime CreatedOn { get; set; }
public ICollection<Label> Labels { get; set; }
public ICollection<Comment> Commennts { get; set; }
public virtual Language Language { get; set; }
public virtual ApplicationUser User { get; set; }
}
public class Label
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Snippet> Snippets { get; set; }
}
Here are my Destination classes:
public class SnippetModels
{
public class Output
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime CreatedOn { get; set; }
public string Code { get; set; }
public string LanguageName { get; set; }
public string UserUsername { get; set; }
public IEnumerable<LabelModels.Output> Labels { get; set; }
//TODO Comments Labels
}
}
public class LabelModels
{
public class Output
{
public int Id { get; set; }
public string Name { get; set; }
}
}
public class HomeViewModel
{
public IEnumerable<SnippetModels.Output> Snippets { get; set; }
public IEnumerable<LabelModels.Output> Labels { get; set; }
}
And finally I tied everything that pop up in my mind but no success:
Mapper.CreateMap<Snippy.Models.Label, LabelModels.Output>();
Mapper.CreateMap<IEnumerable<Snippy.Models.Label>, IEnumerable<LabelModels.Output>>();
Mapper.CreateMap<Snippy.Models.Snippet, SnippetModels.Output>()
.ForMember(dest => dest.Labels, opt => opt.MapFrom(src => src.Labels));
Mapper.CreateMap<IEnumerable<Snippy.Models.Snippet>, IEnumerable<SnippetModels.Output>>();
var newestSnippetsDatabase = this.Data.Snippets
.All()
.OrderByDescending(s => s.CreatedOn)
.Take(HomeVisibleItemsCount)
.Select(s => s)
.ToList();
var homeScreenView = new HomeViewModel
{
Snippets = Mapper.Map<IEnumerable<SnippetModels.Output>>(newestSnippetsDatabase)
};