как программно создать локальную базу данных .mdf?

как программно создать локальную базу данных .mdf?

приемлемые решения исключают визуальную студию, ssms, aspnet_regsql.

наивный взгляд на решение может выглядеть так:

static void Main(string[] args)
{
    using (var con = new SqlConnection(@"Integrated Security=SSPI;Data Source=(LocalDb)\v11.0;AttachDbFilename=test.mdf"))
    {
        con.Open();
        using (var cmd = new SqlCommand("CREATE DATABASE test", con))
        {
            cmd.CommandType = CommandType.Text;
            cmd.ExecuteNonQuery();
        }
    }
}

но, конечно, это не удается в SqlConnection.Open с ошибкой

Не удалось подключить базу данных с автоматическим именем для файла test.mdf. База данных с таким именем существует, или указанный файл не может быть открыт, или он находится в общей папке UNC.

Вы не можете подключиться к базе данных, если указанный .mdf не существует.

Итак... как его создать?


person Spongman    schedule 29.08.2014    source источник
comment
Вы можете использовать SqlLocalDB утилиту для создания, запуска и остановки экземпляров LocalDB. . Когда у вас есть экземпляр, вы можете использовать SQLCMD для выполнения команды, подобной CREATE DATABASE (databasename), для этого нового экземпляра.   -  person marc_s    schedule 30.08.2014
comment
к сожалению, SqlLocalDB не создает .mdf, который можно использовать с AttachDbFilename.   -  person Spongman    schedule 30.08.2014


Ответы (2)


Пришлось собрать воедино несколько ответов из Stackoverflow и отличного Статья о начале работы с SQL Server 2012 Express LocalDB от @AaronBertrand

Код предполагает, что Dapper.NET установлен:

PM> Install-Package Dapper

Программное создание:

var dbServerName = "SERVER_NAME";
var dbName = "DATABASE_NAME";

var infoResult = SqlLocalDbCommand($"info {dbServerName}");

var needsCreated = infoResult?.Trim().EndsWith($"\"{dbServerName}\" doesn't exist!");

if (needsCreated.GetValueOrDefault(false))
{
    var createResult = SqlLocalDbCommand($"create {dbServerName} -s");

    var success = createResult?.Trim().EndsWith($"\"{dbServerName}\" started.");

    if (false == success)
    {
        var msg = $"Failed to create database:{Environment.NewLine}{createResult}"
        throw new ApplicationException(msg);
    }

    var master = $@"Server=(localdb)\{dbServerName};Integrated Security=True;"
    using (var conn = new SqlConnection(master))
    {
        var result = conn.Execute($"CREATE DATABASE {dbName}");
    }

  var @new = $@"Server=(localdb)\{dbServerName};Integrated Security=True;Database={dbName}"
    using (var conn = new SqlConnection(@new))
    {
        //verify i can access my new database
        var tables = conn.Query($"SELECT * FROM {dbName}.INFORMATION_SCHEMA.Tables");
    }
}

Помощник (спасибо T30):

/// <summary>
///     Executes a command against SqlLocalDB
/// </summary>
/// <remarks></remarks>
/// <param name="arguments">The arguments to pass to SqlLocalDB.exe</param>
/// <returns></returns>
/// <exception cref="System.ApplicationException">Error returned from process</exception>
private static string SqlLocalDbCommand(string arguments)
{
    var process = new Process
    {
        StartInfo =
        {
            FileName = "SqlLocalDB",
            Arguments = arguments,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        }
    };

    process.Start();
    //* Read the output (or the error)
    var output = process.StandardOutput.ReadToEnd();
    Console.WriteLine(output);
    var err = process.StandardError.ReadToEnd();
    Console.WriteLine(err);
    process.WaitForExit();

    if (err.Exists()) throw new ApplicationException(err); //Is LocalDB installed?

    return output;
}

Обратите внимание, что с этим решением вы не увидите файлы mdf, я уверен, что они существуют в какой-то пользовательской папке, но ключевой момент заключается в том, что вы будете подключаться по строке подключения

(localdb)\SERVER_NAME;Integrated Security=True;Database=DATABASE_NAME
person Chris Marisic    schedule 18.03.2016

Итак, я так понимаю, что вы на самом деле хотите создать базу данных с именем test в своем экземпляре LocalDB, но у вас нет уже созданного файла MDF для этой базы данных?

Если это так, код, который у вас есть, не будет работать на этапе подключения, поскольку вы попросили его прикрепить файл test.mdf.

Что вы обычно делаете в этой ситуации, так это сначала устанавливаете соединение с основной базой данных, а затем запускаете оператор создания базы данных, который создаст тестовую базу данных со связанным с ней файлом MDF, возможно, попробуйте изменить строку подключения, чтобы она выглядела более похожей на это и затем снова работает:

Integrated Security=SSPI;Data Source=(localdb)\V11.0;Initial Catalog=master
person steoleary    schedule 01.09.2014