C# 如何使用AutoMapper 3和实体框架将整数映射到字符串
我试图使用AutoMapper 3将一个具有Integer属性的类投影到另一个具有String属性的类 执行查询时,我得到以下异常: System.NotSupportedException:LINQ to Entities无法识别方法'System.String ToString()'方法,此方法无法转换为存储表达式。 以下是守则的相关部分:C# 如何使用AutoMapper 3和实体框架将整数映射到字符串,c#,linq,entity-framework,automapper-3,C#,Linq,Entity Framework,Automapper 3,我试图使用AutoMapper 3将一个具有Integer属性的类投影到另一个具有String属性的类 执行查询时,我得到以下异常: System.NotSupportedException:LINQ to Entities无法识别方法'System.String ToString()'方法,此方法无法转换为存储表达式。 以下是守则的相关部分: public partial class Lookup { public int LookupId { get; set; } publ
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));
}
}
公共部分类查找
{
public int LookupId{get;set;}
public int LookupTypeId{get;set;}
公共字符串值{get;set;}
公共整数序列{get;set;}
公共虚拟LookupType LookupType{get;set;}
}
公共类LookupProfile:Profile
{
受保护的覆盖无效配置()
{
CreateMap()
.FormMember(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()
省=_db.Lookups.Project().To().ToList()
问题:
有没有一种方法可以配置LookupProfile来进行正确的映射,并且仍然在Linq内部工作到实体?
或者有没有其他方法可以使投影与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));
}
}
公共类LookupProfile:Profile
{
受保护的覆盖无效配置()
{
CreateMap()
.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项目中使用通过helpers进行客户端验证,则ID字段(如果是数字)将出现验证错误:字段[field]必须是一个数字。
发生这种情况是因为SqlFunctions.StringConvert
的结果返回一个包含多个前导空格的字符串,因此低调的验证器不会将其视为数字
我自己解决这个问题的方法是创建一个通用的SelectListItem
类,该类继承自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);
}
}
}
公共类SelectListItem:SelectListItem
{
公共新T值{
设置{
base.Value=Value.ToString();
}
//我不得不补充一点
//否则代码将无法编译
得到{
返回默认值(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));
}
}
公共类LookupProfile:Profile
{
受保护的覆盖无效配置()
{
//使用任何合适的数据类型:decimal、int、short等
CreateMap()
.ForMember(dest=>dest.Value,opt=>opt.MapFrom(src=>src.LookupId))
.ForMember(dest=>dest.Text,opt=>opt.MapFrom(src=>src.Value));
}
}
最后在服务层,我将实体映射到泛型类,并返回一个IEnumerable
public IEnumerable GetList(){
返回_db.Lookups.Project().To().ToList();
}
通过这种方式,您将为
value
属性获得正确的值,而不带尾随空格。不能SelectListItem。value
是整数吗?我的想法完全相同,但在这种情况下它不能。我确实找到了解决办法,回答了这个问题——很好!也许值得一提的是,这在Project().to()
语法中起作用,因为映射是作为一个转换为SQL的表达式执行的。使用Mapper.Map
这将不起作用。
public IEnumerable<SelectListItem> GetList() {
return _db.Lookups.Project().To<SelectListItem<int>>().ToList();
}