【问题标题】:EFCore SQLite connection string with relative path in asp.netEFCore SQLite 连接字符串与 asp.net 中的相对路径
【发布时间】:2018-03-15 01:30:33
【问题描述】:

我刚刚将 SQLite 添加到我的 asp.net webApi 项目中,但无法确定如何将 App_Data 文件夹的路径传递给 DbContextOptionsBuilderUseSqlite

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

<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" /&gt;,那么当我在我的开发机器上运行调试时,它似乎神奇地找到了 App_Data 文件夹中的文件,但我在另一台机器上遇到了问题(发布版本)。我认为这是路径,尽管我得到的只是“无法打开数据库文件”。

我也试过了..

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

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

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

 connectionString="d:\0\test.sqlite" />

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

有人对此有什么想法吗?

提前致谢

【问题讨论】:

    标签: asp.net sqlite asp.net-web-api ef-core-2.0


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      非常适合我。

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

      【讨论】:

        【解决方案3】:

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

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

        在本例中,您甚至不需要在 ApplicationDbContext.cs 中编写 OnConfiguring(DbContextOptionsBuilder optionsBuilder) 方法。

        您在下面有一个完整的设置(Startup & 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"
          }
        

        【讨论】:

          【解决方案4】:

          在 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

          【讨论】:

            【解决方案5】:

            如果您是使用 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();
                }
            }
            

            如果不存在,此行将创建 Db

            Database.EnsureCreated();
            

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

            【讨论】:

            • 这当然不是一个通用的解决方案。谁说数据库文件总是在那个位置?
            • 你必须在那里创建。其他位置会导致权限问题。访问 API 端点的用户不是服务器或 PC 中的用户。
            猜你喜欢
            • 2020-05-18
            • 2011-06-27
            • 2014-10-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多