咨询:为提升性能,将EF6 CodeFirst的WPF项目从LocalDB迁移至SQLite
嘿,兄弟,我刚好处理过几乎一模一样的场景——单用户WPF + .NET 4.52 + EF6 CodeFirst从LocalDB转SQLite,追求轻量和性能。你说表面看简单,但确实有几个新手容易踩的坑,我给你把步骤和注意事项掰碎了说:
步骤1:搞定NuGet依赖
这是最基础但不能错的一步,别只装个SQLite核心包就完事了:
- 必须安装
System.Data.SQLite和EntityFramework6.SQLite两个包,要选适配.NET 4.52的稳定版本(别贪最新,避免兼容性问题) - 这俩包会自动配置部分基础provider信息,但后续还要手动补全配置文件内容
步骤2:修改连接字符串与DbContext配置
- 把App.config里原来的LocalDB连接字符串换成SQLite格式,示例:
这里提前加了<connectionStrings> <add name="YourDbContextName" connectionString="Data Source=MyAppDb.db;Version=3;Cache Size=10000;" providerName="System.Data.SQLite" /> </connectionStrings>Cache Size参数,后面性能优化会详细说作用。 - 还要在App.config的
entityFramework节点里注册SQLite的provider,否则EF找不到对应的驱动:<entityFramework> <providers> <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> </providers> </entityFramework> - 另外,SQLite的主键自增逻辑和LocalDB有差异,你的实体主键要加上
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]标注,且尽量用int类型(long也支持,但新手用int更不容易出问题)
步骤3:重置CodeFirst迁移(因为你不用保留旧库)
既然旧数据库直接弃用,干脆把之前的迁移记录全清,重新生成适配SQLite的版本:
- 打开Visual Studio的Package Manager Console
- 反复执行
Remove-Migration,直到提示没有可删除的迁移 - 然后执行
Enable-Migrations -EnableAutomaticMigrations(如果之前没开启自动迁移的话) - 最后运行
Update-Database,EF会自动生成全新的SQLite数据库文件
- 注意:SQLite不支持SQL Server的部分特性,比如
DateTimeOffset类型、复杂外键级联删除逻辑,如果实体里有这些,要么换成SQLite支持的类型(比如把DateTimeOffset改成DateTime),要么手动调整迁移代码避免报错
步骤4:针对单用户场景的性能优化(划重点!)
既然你目标是提升性能,单用户下SQLite有几个小技巧能帮上忙:
- 调整缓存大小:刚才连接字符串里的
Cache Size=10000就是干这个的,默认缓存很小,调大后能减少磁盘IO,读写速度会明显提升,单用户可以根据内存情况调到10000甚至更高 - 批量操作一定要开事务:SQLite在事务中执行批量写入的速度比单条提交快N倍,示例代码:
using(var transaction = db.Database.BeginTransaction()) { // 执行你的批量新增/修改操作 db.SaveChanges(); transaction.Commit(); } - 关闭不必要的EF自动检测:在批量操作或者大量查询时,关掉
AutoDetectChangesEnabled能减少额外开销:db.Configuration.AutoDetectChangesEnabled = false; // 执行你的操作 db.Configuration.AutoDetectChangesEnabled = true; // 用完记得恢复默认设置
新手必避的几个坑
- 数据库文件别放安装目录:Windows权限管控严格,程序安装目录(比如C:\Program Files)是只读的,写入会失败,最好把数据库放在用户的应用数据文件夹里,用
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)获取路径 - 处理Decimal类型精度问题:SQLite对Decimal的默认支持不太友好,建议在实体属性上标注
[Column(TypeName = "DECIMAL(18,2)")]指定精度,避免迁移报错或数据精度丢失 - 锁定问题:SQLite是文件级锁,如果程序异常退出,可能导致数据库文件被锁定,这时候直接删掉db文件,重新运行
Update-Database生成新的即可
内容的提问来源于stack exchange,提问作者Obbles
相关产品推荐
相关产品推荐

