web-dev-qa-db-ja.com

SQLiteエラー14:EF Coreコードが最初にある「データベースファイルを開けません」

私は得ています

SQLiteエラー14: 'データベースファイルを開けません'

eF Coreコードを最初にすると、理由はわかりません。私は最初はうまくいきました、データベースファイルはc:\ users\username\AppData\Local\Packages\PackageId\LocalStateに作成されました。

次に、データベースファイルとコードの最初の移行クラスとModelSnapshotクラスを削除し、新しい移行を作成しました(アプリの起動時にDbContext.Database.Migrate()を呼び出して自動的に実行します)。これで、データベースを再度作成することはできなくなりました。

9
IngoB

問題は、SQLiteプロバイダーを使用しているときにEntityFramework Coreがそれ自体でフォルダーを作成できないことだと思います。他のファイルベースのデータベースプロバイダーを使用しているときにも問題が発生するかどうかはわかりません。

私は同じ問題がありました:
私のデータソースは次のようなものでした:optionsBuilder.UseSqlite(@ "Data Source = c:\ foo_db\bar_db.db");

c:\ドライブ内に"foo_db"フォルダーを作成した後、問題は解決され、EF Coreはフォルダー内に.dbファイルを作成しました。

1
darkdog

解決しました。

  1. 「例外設定ウィンドウで」「すべての例外で中断」をアクティブにすると、奇妙な「データベースファイルを開けません」という例外が発生しました。

  2. エンティティークラスの[Table( "TableName")]属性を削除すると、移行クラスで奇妙なテーブル作成動作が発生しました。この属性は、クラス名以外の名前でテーブルを作成する場合にのみ必要だと思いました。

1
IngoB

私の場合、windows 10 Ransomware ProtectionがLINQPad.DriverProxy.LINQPad.Drivers.EFCore.exeによるファイルへのアクセスを妨げていました。ランサムウェア保護下で許可する->ブロック履歴により、このエラーは発生しませんでした。

0
Dean Lunz

2019年8月の時点でもまだ発生しています。上記のすべてを試してみましたが、2時間後の修正は次のとおりです。

このクラスをアプリケーションの任意の場所に追加します。

internal class CurrentDirectoryHelpers
{
    internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
    [System.Runtime.InteropServices.DllImport(AspNetCoreModuleDll)]
    private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    private struct IISConfigurationData
    {
        public IntPtr pNativeApplication;
        [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
        public string pwzFullApplicationPath;
        [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
        public string pwzVirtualApplicationPath;
        public bool fWindowsAuthEnabled;
        public bool fBasicAuthEnabled;
        public bool fAnonymousAuthEnable;
    }
    public static void SetCurrentDirectory()
    {
        try
        {
            // Check if physical path was provided by ANCM
            var sitePhysicalPath = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH");
            if (string.IsNullOrEmpty(sitePhysicalPath))
            {
                // Skip if not running ANCM InProcess
                if (GetModuleHandle(AspNetCoreModuleDll) == IntPtr.Zero)
                {
                    return;
                }
                IISConfigurationData configurationData = default(IISConfigurationData);
                if (http_get_application_properties(ref configurationData) != 0)
                {
                    return;
                }
                sitePhysicalPath = configurationData.pwzFullApplicationPath;
            }
            Environment.CurrentDirectory = sitePhysicalPath;
        }
        catch
        {
            // ignore
        }
    }
}

次に、Program.csで最初に次のように呼び出します。

public static void Main(string[] args)
{
    CurrentDirectoryHelpers.SetCurrentDirectory();
    CreateWebHostBuilder(args).Build().Run();
}

マイセットアップ

  • AspNet Core 2.2 Web API
  • EF Core SQLite 2.2.6
  • 接続文字列を"Filename=./mydatabase.db"に設定

クレジット

私はこの投稿からそれを取りました: https://elanderson.net/2019/02/asp-net-core-configuration-issue-with-in-process-hosting/

0

また、プロジェクトファイル(* .csproj)の "InProcess"を "OutOfProcess"に置き換えることで問題を解決しました。参考になれば幸いです。

0
Erkan Hürnalı

DbContextクラス内でこのコードを試すことができます:

  protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder)
    {
        var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "YourDbName.db");
        optionsBuilder.UseSqlite("Filename = "+dbPath);
        base.OnConfiguring(optionsBuilder);
    }
0
Amara Miloudi

実際の問題は移行後であり、データベースの更新* .dbファイルは自動的にbinフォルダーに移動しません。 * .dbを選択して、「出力ディレクトリにコピー」=「新しい場合はコピー」のプロパティを変更するだけです。これで問題が解決します。試してみてください。

0
Deepak Shaw

これは私にとってはうまくいきます:

    static SqliteConnection CreateConnection()
    {
        string dbPath = Environment.CurrentDirectory + @"\Database.sqlite";
        SqliteConnection conn = new SqliteConnection(@"Data Source = " + dbPath);
        try
        {
            conn.Open();
        }
        catch { }
        return conn;
    }
0
Walter Kohl