如何使用自动映射器 3 和实体框架将整数映射到字符串
本文关键字:映射 框架 整数 字符串 实体 何使用 | 更新日期: 2023-09-27 18:34:13
我正在尝试使用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 实体中工作?或者有没有另一种方法可以使投影与 Linq to Entities 一起使用?
解决方案是使用 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<T>
类,该类继承自SelectListItem
,隐藏原始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);
}
}
}
然后在自动映射器配置文件上,我将映射如下项目:
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
属性的正确值,而不带尾随空格。