【问题标题】:Share Sqlite database between asp.net core project and .net core console project with a third data class library project用第三个数据类库项目在 asp.net core 项目和 .net core 控制台项目之间共享 Sqlite 数据库
【发布时间】:2019-12-23 21:52:00
【问题描述】:

我在 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 核心控制台应用程序中使用其中之一?

这是否适用于跨平台?

【问题讨论】:

    标签: c# .net asp.net-core .net-core entity-framework-core


    【解决方案1】:

    我有点晚了,我假设您已经弄清楚了,但我正在写这个答案,因为它是我的一个谷歌搜索的最佳结果。

    当前的问题是指向数据库的正确位置。

    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.db)。您提供的另一个 blob 应该做同样的事情,但代码行数更多。阅读SqliteConnectionStringBuilder 文档后,似乎后者具有更多功能,允许通过代码添加密码和其他有趣的东西,而不是手动输入字符串。

    绝对路径在这种情况下会有所帮助,因为它允许您指定正在使用的数据库文件的直接路径。否则,您需要修改连接字符串以对每个项目使用相对路径,如果它们要移动到文件系统的不同部分,这可能会变得复杂。它仍然可以完成。例如,如果两个项目位于同一位置,则在数据库名称前附加“../”就足以为所有项目提供相同的位置。

    使用绝对路径,您可以只指定一个位置,如“C:\Chapter.db”,您的所有项目都将使用该位置的数据库,而不是它们的单个文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-28
      • 2021-11-05
      • 2019-07-05
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多