[英]Share Sqlite database between asp.net core project and .net core console project with a third data class library project
我在 vs2019 解决方案中有 3 个项目,它们应该使用 Entity Framework Core 使用相同的 sqlite 数据库。
第一个项目:包含所有数据库模型、数据库上下文、数据库存储库和迁移的 .net 核心类库。
第二个项目:一个 .net 核心控制台应用程序,它需要扫描文件、从 inet 检索元数据并用检索到的内容为数据库做种子。 这是通过引用第一个项目并使用存储库访问数据库来完成的。
第三个项目:一个Asp.net核心Webapi,需要接受客户端请求,从同一个数据库中检索、更新等数据。 这也是通过引用第一个项目并使用存储库来完成的。 这个项目是主项目,需要的时候需要启动第二个项目。
所有项目都需要能够安装在面向 Windows、MacOS 和 Linux 的客户端计算机上。 并自托管。 它必须像一个类似于 Plex、Emby 和 Calibre 的内容服务器。
我的问题是如何创建数据源选项字符串以便能够使用相同的 db 文件并将该文件复制到 Asp.net 核心 Webapi 项目的位置。
我现在在第一个项目的 dbcontext 文件中有这个:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
#region DbSets
public DbSet<Authors> Authors { get; set; }
...
...
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
builder.UseSqlite("Data Source=Chapter.db");
return new ApplicationDbContext(builder.Options);
}
}
这在我的第一个项目的存储库类中:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private DbContextOptionsBuilder<ApplicationDbContext> _optionsBuilder;
public ApplicationDbContext _context = null;
public DbSet<T> table = null;
public GenericRepository()
{
_optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>().UseSqlite("Data Source=Chapter.db");
this._context = new ApplicationDbContext(_optionsBuilder.Options);
table = _context.Set<T>();
}
当我使用实体框架从第一个项目中的迁移创建数据库时,它会在第一个项目的主文件夹中创建 Chapter.db 文件。
在我的 Asp.net Webapi 项目中,我有这个来使用数据库:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite("Data Source=Chapter.db"));
我需要这行代码还是可以使用第一个项目中的存储库类?
当我构建解决方案时,我将所有项目的 dll 放在第三个项目的调试文件夹中,但没有chapter.db 数据库文件。
在为调试和发布而构建时,如何在正确的项目输出目录中自动复制 db 文件?
我需要为 Datasource= 连接字符串使用什么来确保人们安装应用程序后它以 db 文件为目标(在 windows、linux 和 macos 中)?
我已经阅读了两个类似问题的答案以供使用:
Var SqlitePath = Path.combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
@"<YourAppName>\Chapter.db");
和:
var builder = new SqliteConnectionStringBuilder(connectionString);
builder.DataSource = Path.GetFullPath( Path.Combine(
AppDomain.CurrentDomain.GetData("DataDirectory") as string ?
AppDomain.CurrentDomain.BaseDirectory, builder.DataSource);
connectionString = builder.ToString();
这些答案是否具有相同的结果? 我能否在 asp.net 核心项目以及 .net 核心控制台应用程序中使用其中之一?
这是否跨平台工作?
我有点晚了,我假设您已经弄清楚了这一点,但我正在写这个答案,因为它是我的一次谷歌搜索的最佳结果。
手头的问题是指向数据库的正确位置。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite("Data Source=Chapter.db"));
这行代码将在您运行它的任何项目的项目目录中创建一个名为“Chapter.db”的数据库。问题的解决方案已在您的问题底部提供。
Var SqlitePath = Path.combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
@"<YourAppName>\Chapter.db");
此代码会将数据库的相对路径(基于项目目录)转换为绝对路径(基于您的文件系统,即 C:...\\Chapter.db 或 /home/.../Chapter。 D b)。 你提供的另一个 blob 应该做同样的事情,但有更多的代码行。 阅读SqliteConnectionStringBuilder文档后,似乎后者具有更多功能,允许通过代码添加密码和其他有趣的东西,而不是手动输入字符串。
在这种情况下,绝对路径会有所帮助,因为它允许您指定正在使用的数据库文件的直接路径。 否则,您将需要修改连接字符串以对每个项目使用相对路径,如果它们移动到文件系统的不同部分,这可能会变得复杂。 它仍然可以做到。 例如,如果两个项目位于同一位置,则在您的数据库名称前附加“../”就足以为所有项目提供相同的位置。
使用绝对路径,您只需指定一个位置,例如“C:\\Chapter.db”,您的所有项目都将使用该位置的数据库而不是它们的单个文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.