Mapster: сопоставление свойств разных типов. Для типа «CultureInfo» нет конструктора по умолчанию, используйте «ConstructUsing» или «MapWith».
Я использую Mapster версии 7.3.0 и .Net 7.0.1.
У меня два класса.
public class Entity
{
public Guid Id { get; set; }
public string Content { get; set; } = default!;
public string Note { get; set; } = default!;
public CultureInfo CultureInfo { get; set; } = default!;
}
public class Dto
{
[Required, StringLength(64)]
public string Id { get; set; } = default!;
[Required, StringLength(4096)]
public string Content { get; set; } = default!;
[Required, StringLength(1024)]
public string Note { get; set; } = default!;
[Required]
public string CultureName { get; set; } = default!;
}
И с конфигом Mapster
TypeAdapterConfig<Dto, Entity>.NewConfig()
.Map(entity => entity.CultureInfo, dto => CultureInfo.GetCultureInfo(dto.CultureName));
TypeAdapterConfig<Entity, Dto>.NewConfig()
.Map(dto => dto.CultureName, entity => entity.CultureInfo.Name);
Теперь выполните этот код
//Mapster configuration is applied.
var dto = new Dto
{
Id = Guid.NewGuid().ToString(),
Content = "this is a test content",
Note = "for test",
CultureName = "zh-CN"
};
var mLocal = dto.Adapt<Entity>();
var mLocal = dto.Adapt<Entity>();
выдает Mapster.CompileException: ошибка при компиляции.
Mapster.CompileException: Error while compiling
Mapster.CompileException
Error while compiling
source=MindOcean.Models.Common.MessageTemplateLocalizerDto
destination=MindOcean.Data.Entities.MessageTemplateLocalizer
type=Map
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(TypeTuple tuple, MapType mapType)
at Mapster.TypeAdapterConfig.CreateDynamicMapExpression(TypeTuple tuple)
at Mapster.TypeAdapterConfig.<GetDynamicMapFunction>b__66_0[TDestination](TypeTuple tuple)
at Mapster.TypeAdapterConfig.<>c__DisplayClass55_0`1.<AddToHash>b__0(TypeTuple types)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Mapster.TypeAdapterConfig.AddToHash[T](ConcurrentDictionary`2 hash, TypeTuple key, Func`2 func)
at Mapster.TypeAdapterConfig.GetDynamicMapFunction[TDestination](Type sourceType)
at Mapster.TypeAdapter.Adapt[TDestination](Object source, TypeAdapterConfig config)
at Mapster.TypeAdapter.Adapt[TDestination](Object source)
at MindOcean.Test.UnitTest.MapsterTester.TestTwoWay() in /Test/MapsterTester.cs:line 71
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Mapster.CompileException
Error while compiling
source=System.Globalization.CultureInfo
destination=System.Globalization.CultureInfo
type=Map
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context, MemberMapping mapping)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpressionCore(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpression(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
System.InvalidOperationException
No default constructor for type 'CultureInfo', please use 'ConstructUsing' or 'MapWith'
at Mapster.Adapters.BaseAdapter.CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.ClassAdapter.CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInstantiationExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
No default constructor for type 'CultureInfo', please use 'ConstructUsing' or 'MapWith'
Я попробовал использовать MapWith, и это сработало.
TypeAdapterConfig<Dto, Entity>.NewConfig()
.MapWith(dto => new Entity
{
CultureInfo = CultureInfo.GetCultureInfo(dto.CultureName),
Id = Guid.Parse(dto.Id),
Content = dto.Content,
Note = dto.Note,
});
TypeAdapterConfig<Entity, Dto>.NewConfig()
.Map(dto => dto.CultureName, entity => entity.CultureInfo.Name);
я предпочитаюTypeAdapterConfig<Dto, Entity>.NewConfig()
Сюда. Если в доме много объектовEntity
класс, и мне нужно только настроитьCultureInfo
свойство, настройка остальных свойств не требуется, поэтому мне не нужно писать так много ненужного кода. как будто я конвертирую вручную и с большим количеством ненужного кода.
Я хочу знать, есть ли другой способ, а не
MapWith
решить эту проблему конфигурации картографирования Mapster?
1 ответ
Не знаю, почему это не работает, но по крайней мере одним обходным решением может быть игнорирование члена и использование действия после сопоставления:
TypeAdapterConfig<Dto, Entity>.NewConfig()
.Ignore(e => e.CultureInfo)
.AfterMapping((d, e) => e.CultureInfo = CultureInfo.GetCultureInfo(d.CultureName));