AutoMapper с динамическим типом: отсутствует конфигурация карты типов или не поддерживается отображение
Ответ: CreateMissingTypeMaps
должен быть установлен в true
чтобы динамическое отображение работало.
public IEnumerable<T> GetDummies<T>(IEnumerable<dynamic> dummies)
{
var config =
new MapperConfiguration(c => { c.CreateMissingTypeMaps = true; });
IMapper mapper = config.CreateMapper();
return dummies.Select(mapper.Map<T>).ToList();
}
У меня есть оболочка вокруг Entity Framework для выполнения запросов к базе данных. Я хочу, чтобы пользователь мог выбрать только необходимые свойства, но сохранить результат типа объекта.
Это фиктивный код (без использования EF, но с той же проблемой)
class Program
{
static void Main(string[] args)
{
var dummies = new[]
{
new DummyContainer
{
Name = "First",
Description = "First dummy",
DummyNumbers = new List<int> { 1, 2, 3 },
Foo = new FooThingy { Title = "Foo thingy" }
}
};
var smallDummies = dummies.Select(d => new { d.Name }).ToList();
List<DummyContainer> fullDummies = smallDummies.Select(Mapper.Map<DummyContainer>).ToList();
Debugger.Break();
}
}
class DummyContainer
{
public string Name { get; set; }
public string Description { get; set; }
public ICollection<int> DummyNumbers { get; set; }
public FooThingy Foo { get; set; }
}
class FooThingy
{
public string Title { get; set; }
}
Получение этого исключения:
Missing type map configuration or unsupported mapping.
Mapping types:
<>f__AnonymousType0`1 -> DummyContainer
<>f__AnonymousType0`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> AutoMapperWithGenerics.DummyContainer
Destination path:
DummyContainer
Source value:
{ Name = First }
Я немного застрял здесь, потому что в документации говорится, что AutoMapper использует имена свойств для сопоставления с объектом: динамическое сопоставление и сопоставление ExpandoObject.
Обратите внимание, что приведенный выше код является примером. В моем приложении все немного сходит с ума, потому что я на самом деле использую дженерики, например
Mapper.Map<TEntity>
... и так должно быть - я не знаю, какой тип сущности используется. Я ожидаю, просто: сопоставить свойства существующего типа, если отсутствует, установить default(T)
,
Изменить: я пытался указать маппер из dynamic
в T
, почти полный код здесь:
class Program
{
static void Main(string[] args)
{
// ...
var dumminator = new DummyService();
IEnumerable<DummyContainer> bigDummies = dumminator.GetDummies<DummyContainer>(smallDummies);
Debugger.Break();
}
}
class DummyService
{
public IEnumerable<T> GetDummies<T>(IEnumerable<dynamic> dummies)
{
var config = new MapperConfiguration(c => c.CreateMap<dynamic, T>());
IMapper mapper = config.CreateMapper();
return dummies.Select(mapper.Map<T>).ToList();
}
}
... это не умрет при исключении, однако результат будет совершенно пустым (все свойства имеют default
значение.
2 ответа
Вам нужно использовать Mapper.DynamicMap<T>
вместо Mapper.Map<T>
сопоставить с динамическими или анонимными классами
List<DummyContainer> fullDummies = smallDummies.Select(Mapper.DynamicMap<DummyContainer>).ToList();
Вместо устаревших DynamicMap
Вы можете настроить его глобально.
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
Ссылка на вики.
Привет похожий ответ, но не забудьте иметь приватный конструктор в своем классе и не проверять встроенные карты.
public class Player
{
private Player() {}.....
}
var mapper = new MapperConfiguration(cfg =>
{
cfg.ValidateInlineMaps = false;
cfg.CreateMissingTypeMaps = true;
}).CreateMapper();
var player= mapper.Map<Player>(anonymousData);