Automapper Projections and Enum>字符串转换器

时间:2013-04-30 13:48:01

标签: c#-4.0 automapper

使用Automapper的Project().To方法时遇到问题,该方法在执行简单Mapper.Map<>()时未显示。

我有一个映射到字符串的枚举,以及一​​个包含该枚举的类,该枚举映射到包含与enum属性同名的字符串属性的另一个类。

当我从一个班级到另一个班级做一个简单的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();
        }
    }
}

0 个答案:

没有答案