単純Project().To
なMapper.Map<>()
.
文字列にマップされた列挙型と、列挙型プロパティと同じ名前の文字列プロパティを含む別のクラスにマップされたその列挙型を含むクラスがあります。
Mapper.Map<>()
あるクラスから別のクラスに簡単に実行すると、すべて正常に動作します。しかし、 を実行しようとするとProject().To()
、例外が発生します。
System.ArgumentException: Type 'System.String' does not have a default construct
or
at System.Linq.Expressions.Expression.New(Type type)
at AutoMapper.MappingEngine.CreateMapExpression(Type typeIn, Type typeOut)
at AutoMapper.MappingEngine.CreateMapExpression(Type typeIn, Type typeOut)
at AutoMapper.MappingEngine.<CreateMapExpression>b__9[TSource,TDestination](T
ypePair tp)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Fu
nc`2 valueFactory)
at AutoMapper.MappingEngine.CreateMapExpression[TSource,TDestination]()
at AutoMapper.QueryableExtensions.ProjectionExpression`1.To[TResult]()
at ConsoleApplication1.Program.Main(String[] args)
問題を示すコード サンプルを次に示します。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using AutoMapper.QueryableExtensions;
namespace ConsoleApplication1
{
public static class EnumExtensions
{
public static string DisplayName(this Enum e)
{
var field = e.GetType().GetField(e.ToString());
if (field != null)
{
var display = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
if (display != null)
{
return display.Name;
}
}
return e.ToString();
}
}
public enum Foo
{
[Display(Name = "Thing 1")]
Thing1,
[Display(Name = "Thing 2")]
Thing2
}
public class Bar
{
public Foo SomeFoo { get; set; }
public string Name { get; set; }
}
public class BarViewModel
{
public string SomeFoo { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
try
{
// map from enum value to enum display name
AutoMapper.Mapper.CreateMap<Foo, string>().ConvertUsing(x => x.DisplayName());
AutoMapper.Mapper.CreateMap<Bar, BarViewModel>();
AutoMapper.Mapper.AssertConfigurationIsValid();
List<Bar> bars = new List<Bar>();
bars.Add(new Bar() { Name = "Name1", SomeFoo = Foo.Thing2 });
bars.Add(new Bar() { Name = "Name2", SomeFoo = Foo.Thing1 });
var barsQuery = (from Bar b in bars
select b).AsQueryable();
// works exactly as expected
var barViewModesls1 = AutoMapper.Mapper.Map<IEnumerable<BarViewModel>>(barsQuery).ToList();
// throws an exception "Type 'System.String' does not have a default constructor"
var barViewModels2 = barsQuery.Project().To<BarViewModel>().ToList();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.WriteLine("press a key to continue");
Console.ReadKey();
}
}
}