how does one programmatically create a localdb .mdf?

眉间皱痕 提交于 2020-01-01 15:40:47

问题


how does one programmatically create a localdb .mdf?

acceptable solutions exclude visual studio, ssms, aspnet_regsql.

a naive stab at a solution might look like this:

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

but of course, this fails in SqlConnection.Open with the error

An attempt to attach an auto-named database for file test.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.

You cannot connect to a database if the specified .mdf doesn't exist.

So... how do you create one?


回答1:


Had to piece together several answers from Stackoverflow and the great Getting Started with SQL Server 2012 Express LocalDB article from @AaronBertrand

Code assumes Dapper.NET is installed:

PM> Install-Package Dapper

Programmatic creation:

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");
    }
}

Helper (thanks 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;
}

Note that with this solution you won't see the mdf files, i'm sure they exist in some user folder but the key take away is that you'll connect by the connection string

(localdb)\SERVER_NAME;Integrated Security=True;Database=DATABASE_NAME



回答2:


So I take it what you actually want to do is create a database called test in your LocalDB instance, but you don't have an MDF file already created for this database?

If that's the case, the code you have will fail at the connection phase since you've asked it to attach your test.mdf file.

What you would normally do in this situation is make a connection to the master database initially, and then run the create database statement which will create the test database with it's associated MDF file, maybe try changing your connection string so it looks more like this and then running again:

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


来源:https://stackoverflow.com/questions/25577626/how-does-one-programmatically-create-a-localdb-mdf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!