Я использую 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-действия и иметь полный контроль над файлами базы данных.
Если вам действительно нужна / нужна однофайловая локальная база данных производственного уровня, возможно, рассмотрите SQLite, LiteDB или что-то в этом роде, которые не предназначены просто для использования в качестве «инструментов разработки». Большинство из них (по крайней мере, названные) также поддерживают удобное перемещение самого файла, а также "создание из кода" и т.д...
После более глубокого исследования я выяснил следующее:
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 + ";"
Потеря (случайное удаление или перемещение) файлов базы данных приводит к программным исключениям. Чтобы избежать этого и некоторых других неприятных случаев, вы можете сделать некоторые приготовления в начале программы, например:
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);
}
Если вы хотите переместить базу данных в другое место, импортировать или экспортировать, вам следует использовать функции 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);
}
«Я ожидаю, что мои клиенты обязательно будут перемещать базы данных из одного места в другое внутри одного и того же ПК и между ПК» — все, что вам нужно, это строка подключения. Почему что-то еще может быть вашей проблемой? У них есть ИТ-отдел, не так ли? Кроме того, имейте это в виду, LocalDB не предназначен для производства. «Microsoft SQL Server Express LocalDB — это функция SQL Server Express, предназначенная для разработчиков». - Документы