与第三个数据类库项目在asp.net核心项目和.net核心控制台项目之间共享Sqlite数据库

时间:2019-08-18 10:50:06

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

我在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都位于第三个项目的debug文件夹中,而没有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核心控制台应用程序中使用其中之一吗?

那跨平台工作吗?

1 个答案:

答案 0 :(得分:1)

我来晚了,我假设您已经知道了这一点,但是我正在写这个答案,因为它是我的Google搜索之一的最佳结果。

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

created_at

此行代码将在您正在其中运行的任何项目的项目目录中创建一个名为“ Chapter.db”的数据库。问题的解决方案位于问题的底部。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite("Data Source=Chapter.db"));

此代码会将相对于数据库的相对路径(基于项目目录)转换为绝对路径(基于文件系统的绝对路径,即C:... \ Chapter.db或/ home /...。 /Chapter.db)。您提供的另一个Blob应该做同样的事情,但是要用更多的代码行。在阅读SqliteConnectionStringBuilder文档之后,看来后者具有更多功能,允许通过代码添加密码和其他有趣的东西,而不是手动输入字符串。

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

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

相关问题