繁体   English   中英

如何使用AutoMapper 3和Entity Framework将Integer映射到String

[英]How to map Integer to String with AutoMapper 3 and Entity Framework

我试图使用AutoMapper 3将具有Integer属性的类投影到另一个具有String属性的类。

执行查询时,我得到以下异常:

System.NotSupportedException:LINQ to Entities无法识别方法'System.String ToString()'方法,并且此方法无法转换为商店表达式。

以下是代码的相关部分:

public partial class Lookup
{
    public int LookupId { get; set; }
    public int LookupTypeId { get; set; }
    public string Value { get; set; }
    public int SequencialOrder { get; set; }

    public virtual LookupType LookupType { get; set; }
}

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Lookup, SelectListItem>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.LookupId.ToString()))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}

查询看起来像:

Provinces = _db.Lookups.Project().To<SelectListItem>().ToList()

题:

有没有办法我可以配置LookupProfile来进行正确的映射,仍然可以在Linq To Entities中工作? 或者是否有另一种方法可以让Linq与实体一起投影?

解决方案是使用SqlFunctions.StringConvert函数。

以下是修改后的配置文件代码,使一切正常:

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Lookup, SelectListItem>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => SqlFunctions.StringConvert((double)src.LookupId)))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}

我会在这里留下这个答案,以防其他人偶然发现我遇到的同样问题。

当前接受的答案的一个问题是,如果您使用通过帮助程序进行客户端验证的ASP.NET MVC项目,您将获得ID字段的验证错误(如果它是一个数字): The field [field] must be a number. 发生这种情况是因为SqlFunctions.StringConvert的结果返回一个带有几个前导空格的字符串,因此不显眼的验证器不会将其视为数字。

我自己解决这个问题的方法是创建一个继承自SelectListItem的通用SelectListItem<T>类,隐藏原始的Value属性并实现自己的Value setter:

public class SelectListItem<T> : SelectListItem
{
    public new T Value {
        set {
            base.Value = value.ToString();
        }
        // Kind of a hack that I had to add 
        // otherwise the code won't compile
        get {
            return default(T);
        }
    }
}

然后在Automapper配置文件中,我会像这样映射项目:

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        //Use whatever datatype is appropriate: decimal, int, short, etc
        CreateMap<Lookup, SelectListItem<int>>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.LookupId))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}

最后在Service层,我将实体映射到泛型类并返回IEnumerable<SelectListItem>

public IEnumerable<SelectListItem> GetList() {
    return _db.Lookups.Project().To<SelectListItem<int>>().ToList();
}

这样,您将获得Value属性的正确值,而不会有尾随空格。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM