我正在使用AutoMapper将我的实体投影到模型。
这些是我映射到的模型:
public partial class Material
{
public System.Guid Id { get; set; }
public string Description { get; set; }
public string EAN { get; set; }
public virtual InventoryLine InventoryLine { get; set; }
}
public partial class InventoryLine
{
public System.Guid MaterialId { get; set; }
public Nullable<decimal> Quantity { get; set; }
public decimal Price { get; set; }
public Nullable<System.DateTime> LastInspectionDate { get; set; }
public int TransactionsSinceLastInspection { get; set; }
public virtual Material Material { get; set; }
}
public class InventoryLineViewModel
{
public string EAN { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public decimal? Quantity { get; set; }
public DateTime? LastInspectionDate { get; set; }
}
我有这个映射:
CreateMap<Material, InventoryLineViewModel>().ForMember(d => d.Price, o => o.MapFrom(s => s.InventoryLine.Price)).ForMember(d => d.Quantity, o => o.MapFrom(s => s.InventoryLine.Quantity)).ForMember(d => d.LastInspectionDate, o => o.MapFrom(s => s.InventoryLine.LastInspectionDate));
每当我运行此代码时:
Mapper.Initialize(c => { c.AddProfile(new MapperProfile()); });
return context.Material.Include(i => i.InventoryLine).ProjectTo<InventoryLineViewModel>().ToList();
我收到此错误:
转换为值类型'System.Decimal'失败,因为具体化值为null。结果类型的泛型参数或查询必须使用可空类型。
当我映射到的所有类型具有相同的数据类型时,这怎么可能?我甚至尝试在数据库和视图模型中使Quantity
属性不可为空。我仍然得到同样的错误。
感谢任何帮助: - )
答案 0 :(得分:9)
问题是视图模型Price
属性类型不可为空,但由于源InventoryLine
是可选的,因此EF(如异常消息中所建议的)需要能够存储可空的来源为null
时的值。
您可以通过两种方式解决问题:
(A)使视图模型属性可为空:
public class InventoryLineViewModel
{
public decimal? Price { get; set; }
}
(B)保留视图模型并按如下方式更改映射:
.ForMember(d => d.Price, o => o.MapFrom(s => ((decimal?)s.InventoryLine.Price) ?? 0))
或
.ForMember(d => d.Price, o => o.MapFrom(s => s.InventoryLine != null ? s.InventoryLine.Price : 0))
答案 1 :(得分:3)
.NET 4.0,Nullable具有“ GetValueOrDefault()”方法。 因此,如果将查询强制转换为Nullable,则完成后可以得到正确的Type。 此方法还将生成正确的单个SQL SELECT SUM查询,并且比通过linq将整个记录集返回到更高的总和的其他解决方案要快。
decimal result = ((decimal?)query.Where(w => w.Customer =="ABC").Sum(s => (decimal?)s.Amount)).GetValueOrDefault();
答案 2 :(得分:-1)
致电.ToList()
为我解决了此错误。