SQLite与.NET实体类字段类型匹配及格式转换故障排查
解决SQLite + EF6中DECIMAL字段与decimal类型映射的FormatException问题
一、数据库与类字段类型选择方案
- 优先方案:数据库保持
DECIMAL(10,5)字段类型,实体类对应字段用decimal类型。这最贴合业务数据语义,能利用强类型校验,避免后续手动转换的麻烦,只需修复映射转换的问题即可。 - 备选方案:临时将实体类字段设为
string类型,读取后手动转换为decimal处理。但这种方式会增加业务代码的复杂度,且无法在编译阶段做类型校验,仅适合临时应急。
二、解决格式转换报错的具体方法
1. 显式配置EF6的字段映射规则
重写DbContext的OnModelCreating方法,明确指定DECIMAL字段的精度和类型映射,让EF6正确识别字段属性:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置IndexValue字段 modelBuilder.Entity<Index>() .Property(p => p.IndexValue) .HasColumnType("DECIMAL(10,5)") .HasPrecision(10, 5); // 配置Discount字段 modelBuilder.Entity<Index>() .Property(p => p.Discount) .HasColumnType("DECIMAL(10,5)") .HasPrecision(10, 5); }
2. 强制使用不变文化进行格式解析
区域文化差异是这类格式错误的常见原因,直接在应用启动时设置线程默认文化为不变文化,从根源避免逗号/句号的解析冲突:
// 在应用初始化的地方添加 System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
3. 更新SQLite EF6驱动版本
旧版本的System.Data.SQLite.EF6驱动可能存在DECIMAL类型映射的bug,去NuGet更新到最新稳定版,很多时候能直接解决这类兼容性问题。
4. 自定义字段转换逻辑
如果前面的方法都无效,可以在实体类中用私有string字段映射数据库,公开decimal属性做手动转换,强制用不变文化解析:
public class Index { // 映射到数据库的string字段 [Column("IndexValue")] public string IndexValueDb { get; set; } // 业务用的decimal属性,不映射到数据库 [NotMapped] public decimal IndexValue { get => decimal.Parse(IndexValueDb, System.Globalization.CultureInfo.InvariantCulture); set => IndexValueDb = value.ToString(System.Globalization.CultureInfo.InvariantCulture); } // Discount字段按同样逻辑处理 [Column("Discount")] public string DiscountDb { get; set; } [NotMapped] public decimal Discount { get => decimal.Parse(DiscountDb, System.Globalization.CultureInfo.InvariantCulture); set => DiscountDb = value.ToString(System.Globalization.CultureInfo.InvariantCulture); } }
内容的提问来源于stack exchange,提问作者eusataf
相关产品推荐
相关产品推荐

