SQL Server Varchar字段转Decimal时LINQ to Entities报错求助
解决LINQ to Entities不识别
Decimal.Parse的问题 这个报错我太熟了!本质原因是LINQ to Entities会把你的查询转换成SQL语句在数据库端执行,但Decimal.Parse是.NET的本地方法,SQL Server根本不认识它,自然就报错了。结合你的代码场景,给你几个可行的解决办法:
方法1:先加载数据到内存再转换(通用所有EF版本)
把查询分成两步:先从数据库取到需要的原始数据(包括字符串类型的Poids),切换到客户端内存执行后,再用Decimal.Parse转换。这样就绕开了EF无法转换CLR方法的问题:
var list = db.Réception .Where(y => y.Supprimée == false) // 第一步:只从数据库查询需要的字段,先不做转换 .Select(x => new { Id_rec = x.Id_rec, N° = x.N°, Date_rec = x.Date_rec.ToString(), heure_rec = x.heure_rec.ToString(), Qualité = x.Qualité.Qualité1, // 先获取Wg关联表中的Poids字符串 PoidsStr = x.Wg.Where(y => y.Id_rec == x.Id_rec) .Select(w => w.Poids) .FirstOrDefault() }) .AsEnumerable() // 关键:这里切换到客户端内存执行后续操作 // 第二步:在内存中转换字符串为Decimal .Select(item => new { item.Id_rec, item.N°, item.Date_rec, item.heure_rec, item.Qualité, // 建议用TryParse避免格式错误抛出异常 Poids = decimal.TryParse(item.PoidsStr, out decimal poids) ? poids : 0m // 转换失败时的默认值,可根据需求调整 }) .ToList();
注意:如果数据量很大,这种方法会把所有符合条件的记录加载到内存,可能影响性能,所以尽量在AsEnumerable之前做好过滤,减少加载的数据量。
方法2:用EF支持的SQL转换函数(EF Core推荐)
如果你用的是EF Core,可以直接用Convert.ToDecimal或者EF.Functions.TryConvert,EF Core会把这些方法转换成SQL的CAST或TRY_CONVERT语句,在数据库端完成转换:
var list = db.Réception .Where(y => y.Supprimée == false) .Select(x => new { Id_rec = x.Id_rec, N° = x.N°, Date_rec = x.Date_rec.ToString(), heure_rec = x.heure_rec.ToString(), Qualité = x.Qualité.Qualité1, // 用Convert.ToDecimal让EF转换成SQL的CAST Poids = Convert.ToDecimal( x.Wg.Where(y => y.Id_rec == x.Id_rec) .Select(w => w.Poids) .FirstOrDefault() ) }) .ToList();
如果数据库里可能存在无效格式的字符串,推荐用TRY_CONVERT(SQL Server 2012+支持),避免转换失败导致整个查询报错:
Poids = EF.Functions.TryConvert<decimal>( x.Wg.Where(y => y.Id_rec == x.Id_rec) .Select(w => w.Poids) .FirstOrDefault() ) ?? 0m // 转换失败返回默认值
方法3:从根源解决(推荐长期方案)
如果可以修改数据库,直接把Poids字段的类型从Varchar改成Decimal才是一劳永逸的办法。这样既不用每次做转换,也能避免格式错误的问题,还能提升查询性能。当然如果数据库结构不能改,再用上面两种方法。
内容的提问来源于stack exchange,提问作者lot
相关产品推荐
相关产品推荐

