问题
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