Как удалить, воссоздать, переместить, импортировать и экспортировать базы данных LocalDB?

Я использую C# WPF, Entity Framework и MS SQL Server. Мой клиент использует LocalDB.

Я подключаюсь к своей базе данных через следующую строку подключения:

"Server=(localdb)\MSSQLLocalDB; Database=Production; Integrated Security=True;"

И я обнаружил, что база данных сохраняется в виде двух файлов: C:\Users\[username]\Production.mdf и Production_log.ldf.

Допустим, эти два файла потеряны. Итак, я хочу снова создать эту базу данных, а затем импортировать базу данных из другого mdf-файла. Я запускаю свой проект С#, и при этом

using (ProductionContext db = new ProductionContext())
{
    db.Database.EnsureDeleted();
    db.Database.EnsureCreated();
}

метод EnsureCreated() выдает мне следующую ошибку:

База данных «Производство» уже существует. Выберите другое имя базы данных

Кроме того, похоже, что mdf- и ldf-файлы базы данных все еще находятся внутри

C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\DATA

И это меня смущает.

Я пытался удалить mdf- и ldf-файлы в папке Program Files, но это не помогло. Я пытался остановить, удалить и создать экземпляр LocalDB через командную строку (остановка sqllocaldb, удаление sqllocaldb, создание sqllocaldb), но это тоже не помогло. Я также просмотрел системные представления базы данных (например, sys.sysfiles), чтобы найти файлы базы данных, но это не дало мне никакой дополнительной информации.

У меня также были проблемы с перемещением, импортом и экспортом базы данных localdb.

Причина, по которой я задаю этот вопрос, заключается в том, что я ожидаю, что мои клиенты обязательно будут перемещать базы данных из одного места в другое внутри одного и того же ПК и между ПК. Я также хочу предоставить хорошую систему резервного копирования. Итак, мне нужно уметь выполнять простые CRUD-действия и иметь полный контроль над файлами базы данных.

«Я ожидаю, что мои клиенты обязательно будут перемещать базы данных из одного места в другое внутри одного и того же ПК и между ПК» — все, что вам нужно, это строка подключения. Почему что-то еще может быть вашей проблемой? У них есть ИТ-отдел, не так ли? Кроме того, имейте это в виду, LocalDB не предназначен для производства. «Microsoft SQL Server Express LocalDB — это функция SQL Server Express, предназначенная для разработчиков». - Документы

Fildor 28.06.2024 07:56

Если вам действительно нужна / нужна однофайловая локальная база данных производственного уровня, возможно, рассмотрите SQLite, LiteDB или что-то в этом роде, которые не предназначены просто для использования в качестве «инструментов разработки». Большинство из них (по крайней мере, названные) также поддерживают удобное перемещение самого файла, а также "создание из кода" и т.д...

Fildor 28.06.2024 08:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После более глубокого исследования я выяснил следующее:

  1. Вы можете указать папку, в которой хранится ваша база данных, в строке подключения, например:
string myAppName = "MyAppName";
string myDatabaseName = "MyDatabaseName";
string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), myAppName);
string databaseFilePath = Path.Combine(appDataPath, myDatabaseName + ".mdf");
string connectionString = "Server=(localdb)\\" + myAppName + "; Database = " + myDatabaseName + "; Integrated Security=True; AttachDbFilename = " + databaseFilePath + ";"
  1. Потеря (случайное удаление или перемещение) файлов базы данных приводит к программным исключениям. Чтобы избежать этого и некоторых других неприятных случаев, вы можете сделать некоторые приготовления в начале программы, например:

    private void Prepare()
    {
        if (!Directory.Exists(appDataPath)) Directory.CreateDirectory(appDataPath);
    
        using (DbContext db = new DbContext())
        {
            try
            {
                CreateLocalDBInstance();
                db.Database.EnsureCreated();
            }
            catch
            {
                DeleteLocalDBInstance();
    
                CreateLocalDBInstance();
                db.Database.EnsureCreated();
    
                if (!db.Database.CanConnect())
                {
                    MessageBox.Show("Unable to connect to the database");
                    this.Shutdown();
                    return;
                }
            }
        }
    }
    
    private int ExecuteLocalDBCommandCMD(string arguments)
    {
        try
        {
            var proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "sqllocaldb",
                    Arguments = arguments,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };
    
            proc.Start();
            proc.WaitForExit();
    
            return proc.ExitCode;
        }
        catch
        {
            return 1;
        }
    }
    
    private void CreateLocalDBInstance()
    {
        ExecuteLocalDBCommandCMD("create " + myAppName);
        ExecuteLocalDBCommandCMD("start " + myAppName);
    }
    
    private void DeleteLocalDBInstance()
    {
        ExecuteLocalDBCommandCMD("stop " + myAppName);
        ExecuteLocalDBCommandCMD("delete " + myAppName);
    }
  2. Если вы хотите переместить базу данных в другое место, импортировать или экспортировать, вам следует использовать функции BACKUP и RESTORE, например:

public void BackupDatabase(DbContext db, string path)
{
    db.Database.ExecuteSqlRaw("ALTER DATABASE " + myDatabaseName + " SET MULTI_USER WITH ROLLBACK IMMEDIATE");
    File.Delete(path);
    db.Database.ExecuteSqlRaw("BACKUP DATABASE " + myDatabaseName + " TO DISK='" + path + "'");
}

public void RestoreDatabase(DbContext db, string path)
{
    db.Database.EnsureDeleted();
    
    // You can't restore a database in use. You need to switch to another database first
    connectionStringMaster = "Server=(localdb)\\" + myAppName + "; Database=master; Integrated Security=True;";
    
    string? connectionString = db.Database.GetConnectionString();
    db.Database.SetConnectionString(connectionStringMaster);
    
    db.Database.ExecuteSqlRaw("RESTORE DATABASE " + myDatabaseName + " FROM DISK='" + path + "'");
    
    db.Database.SetConnectionString(connectionString);
}

Другие вопросы по теме