How to specify mapping rule when names of properties differ
Never mind, I myself found a solution:
Mapper.CreateMap<Employee, EmployeeDto>()
.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name));
Usage of Automapper when property names are different
You can try recognizing postfixes:
Mapper.Initialize(cfg => {
cfg.RecognizePostfixes("Field");
cfg.CreateMap<Source, Dest>();
});
Recognizing prefixes also works local to profiles, if it's just a set of maps that this applies to.
Automapper: mapping between different types
For mapping both ways this configuration works for me:
var mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Entity, EntityDto>()
.ForMember(dest => dest.EntityChildrenIds, opt => opt.MapFrom(src => src.Children))
.ReverseMap();
cfg.CreateMap<EntityChild, int>().ConvertUsing(child => child.Id);
cfg.CreateMap<int, EntityChild>().ConvertUsing(id => new EntityChild
{
Id = id
});
});
Since the properties have different names we need to configure that mapping.
Then just add general mappings from EntityChild
to int
and back again and we're done.
AutoMapper Mapping one property to two properties by condition
I have found solution. The solution is pretty simple and clear. It turns out as follow:
Full code:
public class Program
{
class A
{
public string ProductionDivision { get; set; }
}
class B
{
private object _productionDivision;
public enum ProductionDivisionOneofCase
{
None = 0,
IsNullproductionDivision = 15,
ProductionDivisionValue = 16,
}
private ProductionDivisionOneofCase _productionDivisionCase = ProductionDivisionOneofCase.None;
public bool IsNullProductionDivision
{
get { return _productionDivisionCase == ProductionDivisionOneofCase.IsNullproductionDivision ? (bool)_productionDivision : false; }
set
{
_productionDivision = value;
_productionDivisionCase = ProductionDivisionOneofCase.IsNullproductionDivision;
}
}
public string ProductionDivisionValue
{
get { return _productionDivisionCase == ProductionDivisionOneofCase.ProductionDivisionValue ? (string)_productionDivision : ""; }
set
{
_productionDivision = value;
_productionDivisionCase = ProductionDivisionOneofCase.ProductionDivisionValue;
}
}
}
public class StrinToBoolCustomResolver
: IValueConverter<string, bool>
{
public bool Convert(string sourceMember, ResolutionContext context)
{
return sourceMember == null;
}
}
public class MyAutoMapperProfile
: Profile
{
public MyAutoMapperProfile()
{
// add post and pre prefixes to add corresponding properties in the inner property map
RecognizeDestinationPostfixes("Value");
RecognizeDestinationPrefixes("IsNull");
// add mapping for "value" property
this.ForAllPropertyMaps(map => map.SourceMember.Name + "Value" == map.DestinationName,
(map, expression) =>
{
expression.Condition((source, dest, sMem, destMem) =>
{
return sMem != null;
});
expression.MapFrom(map.SourceMember.Name);
});
// add mapping for "IsNull" property
this.ForAllPropertyMaps(map => "IsNull" + map.SourceMember.Name == map.DestinationName,
(map, expression) =>
{
expression.Condition((source, dest, sMem, destMem) =>
{
return (bool)sMem;
});
//expression.MapFrom(map.SourceMember.Name);
expression.ConvertUsing<string, bool>(new StrinToBoolCustomResolver(), map.SourceMember.Name);
});
CreateMap<A, B>();
//.ForMember(g => g.IsNullProductionDivision, m =>
//{
// m.PreCondition(s => s.ProductionDivision == null);
// m.MapFrom(b => true);
//});
//.ForMember(g => g.ProductionDivisionValue, m =>
//{
// m.PreCondition(s => s.ProductionDivision != null);
// m.MapFrom(b => b.ProductionDivision);
//});
}
}
public static void Main(string[] args)
{
var configuration = new MapperConfiguration(cfg => {
cfg.AddProfile(new MyAutoMapperProfile());
});
var mapper = new Mapper(configuration);
mapper.ConfigurationProvider.AssertConfigurationIsValid();
var a = new A()
{
ProductionDivision = null
};
// b._productionDivisionCase will be equal IsNullproductionDivision
var b = mapper.Map<B>(a);
var c = new A()
{
ProductionDivision = "dsd"
};
// d._productionDivisionCase will be equal ProductionDivisionValue
var d = mapper.Map<B>(c);
}
}
Clarification:
add (post/pre)fixes to add corresponding properties to inner property map. It need to do here because our properties should be catched by AutoMapper. Otherwise properties will be abandoned and mapper configuration will be failed.
After that, we configurate how these properties need to be mapping. We call
ForAllPropertyMaps
method, filtering all properties and setting a rule to mapping properties suitable with our filter. When the mapper object is creating, the execution plan will be built taking look the specified filters.
- For "Value" property we add a condition to check whether the source property is not null. If it is null, then mapping will be missed.
- For "IsNull" property First of all, we add a converter to convert string type to bool type. The converter just compares the source string property with null value. If the source property equals null, then the converter returns true. So, the condition receives a true value, returns true, and mapping will be done. Otherwise the converter returns false, so the condition returns false and mapping will be missed.
Thus, the mapping of source property will occur to different destination properties depending on whether the source property is null value. Besides that, corresponding set methods of corresponding destination properties will be not called if it not must to be called.
Auto mapper makes error when mapping class with another class properties
The namespace for Data class is different, even though their content is the same.
Delete these
and refer to source Data class namespace or
If you don't want to delete them, add the following configuration
public class CASADetailsProfile: Profile
{
public CASADetailsProfile()
{
// Source -> Target
CreateMap<CASADetialsRequest, CASADetails>();
CreateMap<CASADetails, CASADetialsResponse>();
CreateMap<Sources.Data, Destinations.Data>();
CreateMap<Sources.Account, Destinations.Account>();
CreateMap<Sources.Transaction, Destinations.Transaction>();
CreateMap<Sources.LinkedCard, Destinations.LinkedCard>();
CreateMap<Sources.JointParty, Destinations.JointParty>();
}
}
Change Sources namespace and Destinations namespace to the namespace that you have
How do I get AutoMapper to map classes whose type isn't known at compile time?
Looking at the docs, it seems you can tell AutoMapper about the inheritance like so:
var config = new MapperConfiguration(cfg =>
{
//Other mapping
cfg.CreateMap<v1.Event, v2.Event>() //or even <object, v2.Event>
.Include<v1.Conference, v2.Conference>()
.Include<v1.ReligiousCeremony, v2.ReligiousCeremony>();
cfg.CreateMap<v1.Conference, v2.Conference>();
cfg.CreateMap<v1.ReligiousCeremony, v2.ReligiousCeremony>();
});
Related Topics
C# Constructing Parameter Query SQL - Like %
String.Format - How It Works and How to Implement Custom Formatstrings
How to Quickly Remove Items from a List
Change Custom Attribute's Parameter at Runtime
Best Way to Switch Behavior Based on Type
How to Update an Existing Windows Phone 8 App to Windows Phone Store 8.1
Manipulating Images with .Net Core
How to Implement Permission Based Access Control with ASP.NET Core
Ftp Directory Partial Listing with Wildcards
How to Delete a Row from Gridview
How to Programmatically Limit My Program's CPU Usage to Below 70%
Difference Between Ienumerable Count() and Length
How to Redirect to Index from Another Controller
How to Omit Methods from Swagger Documentation on Webapi Using Swashbuckle
Multiple Where Clauses with Linq Extension Methods