AutoMapper mapping based on containing property name - automapper

Is it possible mapping two classes based on their similar property names:
class Source {
public int uId { get; set; }
public string PrefixRef { get; set; }
...
}
class Destination {
public int Id { get; set; }
public string Prefix { get; set; }
...
}
Thanks.
UPDATE:
-1, smart alek.
I'm totally new to AutoMapper.
Mapper.Initialize(cfg => {
cfg.RecognizePrefixes(new[] { "u" });
cfg.RecognizePostfixes(new[] { "Ref" });
cfg.CreateMap<Source, Destination>();
});

Related

Automapper Object with inside list of object to primitive mapping

I'm trying to create map for automapper to let me map those entity
Entities
public class Entity
{
...
public List<NavigationEntity> Navs { get; set; }
}
public class NavigationEntity
{
public int Id { get; set; }
}
DTO that need to be create with entities
public class EntityDto
{
...
public List<int> NavIds { get; set; }
}
This doesnt seem's to do the job! What could do the job ?
CreateMap<Entity, EntityDto>().ReverseMap();
CreateMap<NavigationEntity, int>().ConstructUsing(x => x.Id);
EDIT
Tried to add
CreateMap< List < SystemsTags >, List< int >>();
but still it doesnt map
First of all, you should rename public List<NavigationEntity> Navs { get; set; } and public List<int> NavIds { get; set; } to the same name. If it is still not working try to also change ConstructUsing to ConvertUsing. And if you need the reverseMap of Entity to EntityDTO you should also add
CreateMap<int, NavigationEntity>().ConvertUsing(x => new NavigationEntity { Id = x });
final code
public class Entity
{
...
public List<NavigationEntity> Navs { get; set; }
}
public class NavigationEntity
{
public int Id { get; set; }
}
public class EntityDto
{
...
public List<int> Navs { get; set; }
}
...
CreateMap<Entity, EntityDto>().ReverseMap();
CreateMap<NavigationEntity, int>().ConvertUsing(x => x.Id);
CreateMap<int, NavigationEntity>().ConvertUsing(x => new NavigationEntity { Id = x });

AutoMapper .ReverseMap() .Ignore() not working

Having an issue with version 6.1.1. In the below, the result of the reverse map still has the Company object populated. Per this post, which shows what I am doing below, except they are ignoring a property, and I'm ignoring a complex object.
What am I missing?
CreateMap<Item, ItemViewModel>(MemberList.Destination)
.ReverseMap()
.ForMember(x => x.Company, x => x.Ignore())
;
With AutoMapper 6.1 you could use ForPath instead ForMember to ignore complex objects.
See How to ignore property with ReverseMap for further information.
I see not what is wrong, but here is a running sample:
namespace AutomapperTest2
{
internal class Program
{
#region Methods
private static void Main(string[] args)
{
// Configure the mappings
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ApplicantEducation, ApplicantEducationVM>();
cfg.CreateMap<Applicant, ApplicantVM>().ReverseMap()
.ForMember(x => x.Education, x => x.Ignore());
});
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
var mapper = config.CreateMapper();
Applicant ap = new Applicant
{
Name = "its me",
Education =
new ApplicantEducation
{
SomeInt = 10,
SomeString = "sampleString"
}
};
// Map
ApplicantVM apVm = Mapper.Map<Applicant, ApplicantVM>(ap);
Applicant apBack = Mapper.Map<ApplicantVM, Applicant>(apVm);
}
#endregion
}
/// Your source classes
public class Applicant
{
public ApplicantEducation Education { get; set; }
public string Name { get; set; }
}
public class ApplicantEducation
{
public int SomeInt { get; set; }
public string SomeString { get; set; }
}
// Your VM classes
public class ApplicantVM
{
public string Description { get; set; }
public ApplicantEducationVM Education { get; set; }
public string Name { get; set; }
}
public class ApplicantEducationVM
{
public int SomeInt { get; set; }
public string SomeString { get; set; }
}
}
}

Automapper How to devide properties from one object to properties of two objects same type

I have one object AllDriversDetails that contains data for two driver: First and Second.
public class AllDriversDetails
{
public string FirstDriverId { get; set; }
public string FirstDriverName { get; set; }
public string SecondDriverId { get; set; }
public string SecondDriverName { get; set; }
}
I have to convert AllDriversDetails to ComplexDriversDetails that has two properties of same type
public class ComplexDriversDetails
{
public DriverDetails FirstDriver { get; set; }
public DriverDetails SecondDriver { get; set; }
}
public class DriverDetails
{
public string Id { get; set; }
public string Name { get; set; }
}
Is it possible to do with automapper?
I should be no problem. Try something like this
Mapper.CreateMap<AllDriversDetails, ComplexDriversDetails>()
.ForMember(m => m.FirstDriver, opt => opt.MapFrom(src => new DriverDetails {Id = src.FirstDriverId, Name = FirstDriverName }))
.ForMember(m => m.SecondDriver , opt => opt.MapFrom(src => new DriverDetails {Id = src.SecondDriverId, Name = SecondDriverName }))
You can find more information here: http://cpratt.co/using-automapper-creating-mappings/

Sequence contains more than one matching element - composite key

When you try to create a one-to-many relationship from the use a composite key, I get the error "the sequence contains more than one matching element"
Help me please!
modelBuilder.Entity<PracticePilotScoringInfo>()
.HasKey(info => new { info.DriverName, info.Control,info.VehicleClass, info.ScoringInfoId });
modelBuilder.Entity<PracticeScoringInfo>()
.HasKey(info => info.Id)
.HasMany(info => info.PracticePilotScoringInfos)
.WithRequired(info => info.ScoringInfo)
.HasForeignKey(info => new { info.DriverName, info.Control, info.VehicleClass, info.ScoringInfoId });
public class PracticeScoringInfo : ScoringInfo
{
public int GrandPrixId { get; set; }
public GrandPrix GrandPrix { get; set; }
public virtual ICollection<PracticePilotScoringInfo> PracticePilotScoringInfos { get; set; }
}
public class PracticePilotScoringInfo : PilotScoringInfo
{
public string DriverName { get; set; }
public ControlType Control { get; set; }
public string VehicleClass { get; set; }
public Guid ScoringInfoId { get; set; }
public virtual PracticeScoringInfo ScoringInfo { get; set; }
}
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
Looks like I'm not identified in Fluent API mapping.
declaration a below is working fine
modelBuilder.Entity<ScoringInfo>()
.HasKey(info => info.Id);
modelBuilder.Entity<PracticeScoringInfo>()
.HasKey(info => info.Id);
modelBuilder.Entity<PilotScoringInfo>()
.HasKey(info => new { info.DriverName, info.Control, info.VehicleClass, info.ScoringInfoId });
modelBuilder.Entity<PracticePilotScoringInfo>()
.HasKey(info => new { info.DriverName, info.Control, info.VehicleClass, info.ScoringInfoId });

Complex collections with Automapper

Here is what I have where I hope someone can help us out:
class Source
{
string name { get; set; }
Inner { get; set; }
}
class Inner
{
Col A { get; set; }
Col B { get; set; }
}
class Col : IList<ClassX>, IEnunmerable<ClassX>
I need to map class Source to a destination type which has:
class Dest
{
string name { get; set; }
IList<ClassY> A { get; set;}
IList<ClassY> B { get; set;}
}
Now, ClassX and class ClassY share the same properties. ClassY class has a subset of the ClassX primitive properties with the exact same names and types.
Tried all kinds of mappings. Just the ClassX to ClassY map, with the collections, without and with any mapping get no mapping found between or missing configuration between Source and Dest
AutoMapper.Mapper.Map<Source, Dest>(src);
Can someone help me out with the mapping? Thanks in advance.
This question is a few months old, but if you're still looking for an answer, this is what I tried that worked:
class Source
{
public string Name { get; set; }
public Inner Inner { get; set; }
}
class Inner
{
public Col A { get; set; }
public Col B { get; set; }
}
class Col : List<ClassX> { }
class ClassX
{
public int Index { get; set; }
public string Name { get; set; }
public ClassX() : this(0, "") { }
public ClassX(int index, string name)
{
this.Index = index;
this.Name = name;
}
}
class ClassY
{
public int Index { get; set; }
public string Name { get; set; }
public ClassY() : this(0, "") { }
public ClassY(int index, string name)
{
this.Index = index;
this.Name = name;
}
}
class Dest
{
public string Name { get; set; }
public List<ClassY> A { get; set; }
public List<ClassY> B { get; set; }
}
[TestMethod]
public void ComplexTest()
{
Mapper.CreateMap<Source, Dest>()
.ForMember(dest => dest.A, config => config.MapFrom(src => src.Inner.A))
.ForMember(dest => dest.B, config => config.MapFrom(src => src.Inner.B));
Mapper.CreateMap<ClassX, ClassY>();
Source source = new Source
{
Name = "Source",
Inner = new Inner
{
A = new Col
{
new ClassX(1, "First"),
new ClassX(2, "Second"),
new ClassX(3, "Third"),
new ClassX(4, "Fourth"),
},
B = new Col
{
new ClassX(5, "Fifth"),
new ClassX(6, "Sixth"),
new ClassX(7, "Seventh"),
new ClassX(8, "Eighth"),
},
}
};
Dest destination = Mapper.Map<Source, Dest>(source);
Assert.AreEqual(source.Name, destination.Name);
Assert.AreEqual(source.Inner.A.Count, destination.A.Count);
Assert.AreEqual(source.Inner.B.Count, destination.B.Count);
Assert.AreEqual(source.Inner.A[0].Name, destination.A[0].Name);
Assert.AreEqual(source.Inner.B[0].Name, destination.B[0].Name);
}
I didn't go too in-depth with my Asserts, so there may be something I missed, but they appear to be mapped properly.

Resources