Answer: CreateMissingTypeMaps
must be set to true
to make dynamic mapping working.
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();
}
I have wrapper around Entity Framework to perform queries to database. I want to allow user to select only required properties, but keep result of entity type.
This is dummy code (without using EF, but having same issue)
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; }
}
Getting this exception:
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 }
I'm bit stuck here, because documentation states that AutoMapper uses property names to map back to object: Dynamic and ExpandoObject Mapping.
Please note that code above is example. In my application, things get bit crazy as I'm actually using generics, e.g.
Mapper.Map<TEntity>
... and it should stay this way - I don't know what entity type is used. My expectation is just: map properties to existing type, if missing, set default(T)
.
Edit: I tried to specify mapper from dynamic
to T
, almost full code here:
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();
}
}
... this won't die on exception, however result is desperately empty (all properties have default
value.
You need to use Mapper.DynamicMap<T>
instead of Mapper.Map<T>
to map from dynamic or anonymous classes
List<DummyContainer> fullDummies = smallDummies.Select(Mapper.DynamicMap<DummyContainer>).ToList();