Mapping 2 objects to poco - issue when mapping the other way
I thought I would flag an issue I observed.
When following the example in https://github.com/MapsterMapper/Mapster/wiki/Custom-mapping Example 2: Mapping 2 objects to poco there seems to be an issue when reversing the mapping. Creating a new tuple from from a poco is fine, but updates do not work.
Example code
const bool ShowScript = true;
void Main()
{
TypeAdapterConfig.GlobalSettings.Compiler = exp => exp.CompileWithDebugInfo();
string script;
// Tuple to POCO
TypeAdapterConfig<(AuthorizationGroup authorizationGroup, GroupDetails groupDetails), GroupDM>
.NewConfig()
.Map(dest => dest, src => src.authorizationGroup)
.Map(dest => dest, src => src.groupDetails);
AuthorizationGroup authorizationGroup = new() { Description = "TEST" };
GroupDetails groupDetails = new() { GroupId = 10 };
if(ShowScript)
{
script = (authorizationGroup, groupDetails).BuildAdapter()
.CreateMapExpression<GroupDM>()
.ToScript();
Console.WriteLine(script);
script = (authorizationGroup, groupDetails).BuildAdapter()
.CreateMapToTargetExpression<GroupDM>()
.ToScript();
Console.WriteLine(script);
}
// Lets create a new instance of GroupDM: Works
var obj = (authorizationGroup, groupDetails).Adapt<GroupDM>();
// Now lets update
authorizationGroup.Description = "UPDATED TEST";
groupDetails.GroupId = 50;
// Now lets update GroupDM: Works
(authorizationGroup, groupDetails).Adapt(obj);
// POCO to Tuple
TypeAdapterConfig<GroupDM, (AuthorizationGroup authorizationGroup, GroupDetails groupDetails)>
.NewConfig()
.Map(dest => dest.authorizationGroup, src => src)
.Map(dest => dest.groupDetails, src => src);
GroupDM groupDM = new() { Name = "Hello world", Description = "Jon Bon Jovi" };
if (ShowScript)
{
script = groupDM.BuildAdapter()
.CreateMapExpression<(AuthorizationGroup authorizationGroup, GroupDetails groupDetails)>()
.ToScript();
Console.WriteLine(script);
script = groupDM.BuildAdapter()
.CreateMapToTargetExpression<(AuthorizationGroup authorizationGroup, GroupDetails groupDetails)>()
.ToScript();
Console.WriteLine(script);
}
// Create a new instance of (AuthorizationGroup, GroupDetails): This works
var tuple = groupDM.Adapt<(AuthorizationGroup authorizationGroup, GroupDetails groupDetails)>();
// Now lets update poco
groupDM.GroupId = 99;
groupDM.Description = "Led Zep";
//Now lets update tuple: Doesn't work
groupDM.Adapt(tuple);
}
public class GroupDM
{
public int GroupId;
public string Name { get; set; }
public string Description { get; set; }
}
public class AuthorizationGroup
{
public string Name { get; set; }
public string Description { get; set; }
}
public class GroupDetails
{
public int GroupId { get; set; }
}
The expression scripts produced suggest that CreateMapToTargetExpression on poco to tuple is incorrect as it is exactly the same as CreateMapExpression
// New: Tuple to POCO
public GroupDM Main(ValueTuple<AuthorizationGroup, GroupDetails> p1)
{
return new GroupDM()
{
Name = p1.Item1.Name,
Description = p1.Item1.Description,
GroupId = p1.Item2.GroupId
};
}
// Update: Tuple to POCO
public GroupDM Main(ValueTuple<AuthorizationGroup, GroupDetails> p1, GroupDM p2)
{
GroupDM result = p2 ?? new GroupDM();
result.Name = p1.Item1.Name;
result.Description = p1.Item1.Description;
result.GroupId = p1.Item2.GroupId;
return result;
}
// New: POCO to Tuple
public ValueTuple<AuthorizationGroup, GroupDetails> Main(GroupDM p1)
{
return p1 == null ? default(ValueTuple<AuthorizationGroup, GroupDetails>) : new ValueTuple<AuthorizationGroup, GroupDetails>(p1 == null ? null : new AuthorizationGroup()
{
Name = p1.Name,
Description = p1.Description
}, p1 == null ? null : new GroupDetails() {GroupId = p1.GroupId});
}
// Update: POCO to Tuple
public ValueTuple<AuthorizationGroup, GroupDetails> Main(GroupDM p1, ValueTuple<AuthorizationGroup, GroupDetails> p2)
{
return p1 == null ? default(ValueTuple<AuthorizationGroup, GroupDetails>) : new ValueTuple<AuthorizationGroup, GroupDetails>(p1 == null ? null : new AuthorizationGroup()
{
Name = p1.Name,
Description = p1.Description
}, p1 == null ? null : new GroupDetails() {GroupId = p1.GroupId});
}
Thanks in advance,
Chris
Hello, named tuple, not named before compile. then always == Tuple<type1, type2> with tipe1 item1, type2 item2. You mapping for name, but name Not achievable, including for reflection, and after compile. Name use only when development type helpers
Hello @ChristoGC If You get This Result?
[TestMethod]
public void MappedNamedTuple()
{
TypeAdapterConfig<GroupDM604, (AuthorizationGroup604 authorizationGroup, GroupDetails604 groupDetails)>
.NewConfig()
.Map(dest => dest.authorizationGroup, src => src)
.Map(dest => dest.groupDetails, src => src);
GroupDM604 groupDM = new() { Name = "Hello world", Description = "Jon Bon Jovi" };
// Create a new instance of (AuthorizationGroup, GroupDetails): This works
var tuple = groupDM.Adapt<(AuthorizationGroup604 authorizationGroup, GroupDetails604 groupDetails)>();
// Now lets update poco
groupDM.GroupId = 99;
groupDM.Description = "Led Zep";
//Now lets update tuple: Doesn't work
groupDM.Adapt(tuple);
tuple.groupDetails.GroupId.ShouldBe(99); // true
tuple.authorizationGroup.Description.ShouldBe("Led Zep"); // true
}