今天早上打开电脑打算写最近在学的WPF的demo,项目原来用的数据库是SQLSERVER但是突然觉得这种桌面应用用SQLite这样的数据库是不是更好,反正使用的ORM是EFCore了解到是支持切换数据库的,于是就试试
分析下怎么做为什么这么做
因为是自己学习写在玩的项目也没有什么数据量,所有我们就忽略掉原来的几条数据
根据我的项目结构发现主要修改下面两个地方就行

- 删除EntityFrameworkCore.SqlServer包并新添加EntityFrameworkCore.Sqlite(这里不知道可不可以不删直接添加)
- 修改MyDbContext,后续要删除之前的迁移并重新update
具体实现步骤
1、 更新包(这里我试下不删直接加的方式,考虑后续是否可以/需要切换回来)
这里我安装和其他的包版本一样的防止有什么bug

2、更新MyDbContext中的OnConfiguring
原来是:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string conStr = "Server = . ;Database = DailyAppWPF;Trusted_Connection = true";
optionsBuilder.UseSqlServer(conStr);
}
更新后:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
#region 数据库使用SqlServer 需要搭配EntityFrameworkCore.SqlServer
string conStr = "Server = . ;Database = DailyAppWPF;Trusted_Connection = true";
optionsBuilder.UseSqlServer(conStr);
#endregion
#region 数据库使用SQLite 需要搭配EntityFrameworkCore.Sqlite
optionsBuilder.UseSqlite("Data Source=DailyAppWPF.db");
#endregion
}
3、删除之前的迁移记录并生成新的
- 使用迁移命令
Add-Migration SqliteInit
这里发现有报错
太长了懒得看复制给元宝问下
嗯,用户遇到了EF Core添加迁移时的错误,看起来是关于多个数据库提供程序注册冲突的问题。用户执行了"Add-Migration SqliteInit"命令,但系统抛出了InvalidOperationException异常。
从错误信息来看,问题核心在于服务提供程序中同时注册了SQL Server和SQLite两个数据库提供程序。EF Core的设计要求一个服务提供程序只能注册一个数据库提供程序,否则会产生冲突。
好抽象,刚刚忘记注释sqlserver的部分了,注释后再试下 发现是可以的
- 更新数据库
Update-database
在解决方案资源管理器里看到下图的这个.db文件就是成功了
到这里就算切换完成了我们启动程序注册一个新用户试试
挺抽象的错误因为我是有这个表的
在注册服务debug 试试吧
Microsoft.Data.Sqlite.SqliteException
HResult=0x80004005
Message=SQLite Error 1: 'no such table: T_User'.
Source=Microsoft.Data.Sqlite
StackTrace:
在 Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
在 Microsoft.Data.Sqlite.SqliteCommand.d__64.MoveNext()
在 Microsoft.Data.Sqlite.SqliteCommand.d__54.MoveNext()
在 Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
在 Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
在 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
在 Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.InitializeReader(Enumerator enumerator) 在 Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.MoveNext()
在 System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable1 source, Boolean& found) 在 System.Linq.Queryable.FirstOrDefault[TSource](IQueryable1 source, Expression`1 predicate)
在 DailyAPP.WPF.Domain.Serve.UserManagerServe.AddUserAsync(AccountInfoDTO account) 在 E:\Code\项目--学习\WPF(Prism)+WebAPI\DailyAPP.WPF - 独立运行版本\DailyAPP.WPF\Domain\Serve\UserManagerServe.cs 中: 第 29 行
此异常最初是在此调用堆栈中引发的:
[外部代码]
DailyAPP.WPF.Domain.Serve.UserManagerServe.AddUserAsync(DailyAPP.WPF.DTOs.AccountInfoDTO) (位于 UserManagerServe.cs 中)
这里catch到一堆的异常突然好像明白了,因为.db文件是在解决方案文件夹下的是否和那些图片一样需要是始终复制的属性试试

尝试了上述的方式不行,然后我把原来的相对路径换成绝对路径就可以了不知道哪位大神评论区可以教我一下感谢
已经搞明白了先说下做法有两种
- 绝对路径
这里直接写数据库文件的绝对路径就行了不用设置什么,缺点是发布的时候不方便
- 相对路径
一开始我设置属性为资源,始终复制

报错如下

换成内容,始终复制就好了
太抽象了,这里还是不懂

这里说下表面的原因
打开下图目录中的.db文件发现是有表的

打开debug目录下.db文件发现没有表

最后就剩一个问题为什么用资源始终复制会报错但是换成内容始终复制就正常了
上面写绝对路径的方法只是用来验证实际不推荐使用
ai大神回答了上面的问题
资源(Resource):
文件会被编译到程序集内部(如 .dll 或 .exe),成为嵌入资源(Embedded Resource)。
运行时需通过 GetManifestResourceStream 等接口访问,不可直接通过文件路径访问。
内容(Content):
文件仅被复制到输出目录(如 bin\Debug),不参与编译,保留独立文件形态。
运行时可通过相对路径直接访问(如 ./data/config.json)。
2. “始终复制”的冲突
当文件标记为 “资源” + “始终复制” 时:
编译阶段:文件被嵌入程序集。
输出阶段:文件又被复制到输出目录,导致同一文件存在两份(程序集内嵌 + 输出目录独立文件)。
冲突结果:运行时可能因资源加载逻辑混乱而报错(如尝试从程序集加载资源,但路径指向了外部文件)。
内容(Content) 无此问题:
文件仅被复制到输出目录,无嵌入过程,路径访问逻辑一致。




浙公网安备 33010602011771号