asp.net 中具有相对路径的 EFCore SQLite 连接字符串

EFCore SQLite connection string with relative path in asp.net

我刚刚将 SQLite 添加到我的 asp.net webApi 项目中,但我无法弄清楚如何获取 App_Data 文件夹的路径以传递给 DbContextOptionsBuilderUseSqlite

我在 web.config 中有以下内容 我有一个 link 到带有连接字符串的外部配置文件...

<connectionStrings configSource="config\connectionStrings.config"/>

在那里我有...

    <connectionStrings>
      <add name="MyDatastore"
             connectionString="DataSource=./App_Data/test.sqlite" />
    </connectionStrings>

在我的 DbContext.OnConfiguring 我有....

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
          if (!optionsBuilder.IsConfigured)
          {
            string path = WebConfigurationManager.ConnectionStrings["MyDatastore"].ConnectionString;
            optionsBuilder.UseSqlite(path);
          }
    }

正确检索到路径(我可以看到我得到了 connectionStrings.config

上配置的路径

所以 ./App_Data/test.sqlite 被传递给 optionsBuilder.UseSqlite(path).

但是,我收到以下错误...

SQLite Error 14: 'unable to open database file'. 

如果我只使用 connectionString="DataSource=test.sqlite" /> 那么它似乎神奇地在 App_Data 文件夹中找到了文件,当我 运行 在我的开发机器上调试时,但我在另一台机器(发布版本)。我认为这是路径,尽管我得到的只是 'unable to open database file'.

我也试过了..

 connectionString="DataSource=|DataDirectory|test.sqlite" />

这给了我一个 Illegal characters in path 错误。

以下确实有效(完整路径)

 connectionString="d:[=16=]\test.sqlite" />

但我希望能够使用相对路径,例如甚至 .\datastore\test.sqlite

有人对此有什么想法吗?

提前致谢

您必须在运行时修复相对路径:

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();

非常适合我。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    var dataSource = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "siteDB.db");
    optionsBuilder
        .UseSqlite($"Data Source={dataSource};");
}

注意:此解决方案已针对 .Net Core 5 进行测试,可以假定它适用于 2.x、3.x、5

如果您想使用与开始时提供的项目不同的项目,您必须指定正确的路径(“Data Source = ..\\MyApplication.DAL\\sqliteDatabase.db” ) 在 appsettings.json.

在本例中,您甚至不需要在 ApplicationDbContext.cs.

中编写方法 OnConfiguring(DbContextOptionsBuilder optionsBuilder)

您有一个完整的设置(启动和 appsettings.json)。

我的项目结构:

 -> MyApplication (solution)
      -> MyApplication.UI (initial project of the solution)
      -> MyApplication.BL (project)
      -> MyApplication.DAL (project)

里面Startup.cs

 public void ConfigureServices(IServiceCollection services)
        {
           //... other services 
           
           services.AddDbContext<ApplicationDbContext>
                (x => x.UseSqlite(Configuration.GetConnectionString("SqliteConnection"))); 
           
           //.... other services and logic
        }

在appsettings.json中:

 "ConnectionStrings": {
    "SqliteConnection": "Data Source = ..\MyApplication.DAL\sqliteDatabase.db"
  }

如果您是使用 sqlite 的 .Net Core 后端开发人员,请务必使用以下代码示例。否则会出现SQLite Error 14: 'unable to open database file'错误

Startup.cs

var baseDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string dbPathSystemLog = Path.Combine(baseDirectory, "CAMSCoreSystemLog.db");

SystemLogDBContext.cs

public class SystemLogDBContext : DbContext
{
    public SystemLogDBContext(DbContextOptions<SystemLogDBContext> options) : base(options)
    {
        Database.EnsureCreated();
    }
}

如果数据库不存在,此行将创建数据库

Database.EnsureCreated();

我挣扎了两天。这将帮助某人。

适用于 linux、.net core 5。

var builder = new SqliteConnectionStringBuilder("Data Source=MyDatabase.db");
builder.DataSource = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, builder.DataSource);

services.AddDbContext<MyContext>(o => o.UseSqlite(builder.ToString());

假设数据库在 bin 目录中,例如MyProject/bin/Debug/MyDatabase.dbMyProject/bin/Release/MyDatabase.db.