Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

PreserveReference is using the src PropertyName to set the Destination property.

Open OFark opened this issue 1 year ago • 3 comments

public sealed record FirstType()
{
	public bool ChargeToAccount {get; init;}
	public string Name {get; set;}
}

public sealed record SecondType()
{
	public bool CanChargeToAccount { get; init; }
	public string Name { get; set; }
}

If I run:

TypeAdapterConfig.GlobalSettings.ForType<FirstType, SecondType>()
		   .PreserveReference(true).Map(st => st.CanChargeToAccount, ft => ft.ChargeToAccount);
	
	var ft = new FirstType() { ChargeToAccount = true, Name = "Jeff"};
	
	var st = ft.Adapt<SecondType>();	

The generated script is:

public UserQuery.SecondType Main(UserQuery.FirstType p1)
{
    if (p1 == null)
    {
        return null;
    }
    MapContextScope scope = new MapContextScope();
   
    try
    {
        object cache;
       
        Dictionary<ReferenceTuple, object> references = scope.Context.References;
        ReferenceTuple key = new ReferenceTuple(p1, typeof(UserQuery.SecondType));
       
        if (references.TryGetValue(key, out cache))
        {
            return (UserQuery.SecondType)cache;
        }
        UserQuery.SecondType result = new UserQuery.SecondType();
        references[key] = (object)result;
       
        typeof(UserQuery.SecondType).GetProperty("ChargeToAccount").SetValue(result, (object)p1.ChargeToAccount);
        result.Name = p1.Name;
        return result;
    }
    finally
    {
        scope.Dispose();
    }
   
}

note this line: typeof(UserQuery.SecondType).GetProperty("ChargeToAccount").SetValue(result, (object)p1.ChargeToAccount);

should be typeof(UserQuery.SecondType).GetProperty("CanChargeToAccount").SetValue(result, (object)p1.ChargeToAccount);

CanChargeToAccount is coming through as ChargeToAccount which isn't a valid property for SecondType.

FYI Mapster 7.3.0 produces the right script:

public UserQuery.SecondType Main(UserQuery.FirstType p1)
{
    if (p1 == null)
    {
        return null;
    }
    MapContextScope scope = new MapContextScope();
   
    try
    {
        object cache;
       
        Dictionary<ReferenceTuple, object> references = scope.Context.References;
        ReferenceTuple key = new ReferenceTuple(p1, typeof(UserQuery.SecondType));
       
        if (references.TryGetValue(key, out cache))
        {
            return (UserQuery.SecondType)cache;
        }
        UserQuery.SecondType result = new UserQuery.SecondType();
        references[key] = (object)result;
       
        result.CanChargeToAccount = p1.ChargeToAccount;
        result.Name = p1.Name;
        return result;
    }
    finally
    {
        scope.Dispose();
    }
   
}

OFark avatar Feb 23 '24 17:02 OFark

In order to identify issues that are still active, we are closing issues that we believe are either resolved or are dormant. If your issue is still active then please reopen. Thanks.

stagep avatar Jan 07 '25 17:01 stagep

Well, I'm still using Mapster 7.3.0 everywhere because I can't upgrade to 7.4.0 because of this issue, so I would say, yes, it's still an issue.

OFark avatar Jul 09 '25 12:07 OFark

@OFark Try latest pre-release version. For Record types this should work.

For Сlasses this also doesn't work in Mapster Tool yet, but for a different reason. upd (fix in #808 )

DocSvartz avatar Jul 09 '25 14:07 DocSvartz