4

我正在尝试使用 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 to Entities 一起工作?

4

2 回答 2

4

解决方案是使用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));

    }
}
于 2013-10-05T14:59:51.313 回答
2

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

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

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

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));

    }
}

最后在服务层,我会将实体映射到泛型类并返回一个IEnumerable<SelectListItem>.

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

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

于 2014-01-01T22:16:28.610 回答