Изменения LocalDB сохраняются в разных файлах mdf. Почему?

Я пытаюсь перестроить приложение, которое изначально использовало sqlite, чтобы теперь использовать «localdb». (Мне нужно приложение, которое может создавать свою собственную базу данных локально и во время выполнения, не требуя предварительно установленного экземпляра SQL Server или SQL Express на целевой машине)

Я хочу отказаться от использования «сторонней» библиотеки (sqlite), поскольку опыт подсказывает мне, что заставить ее работать с нуля может быть сложно, и перейти к чему-то предположительно более простому, чтобы начать работу с нуля.

Используя код, скопированный (и слегка измененный) из Интернета, мне удалось создать файл mdf динамически/программно, но я озадачен тем, что произойдет, если я запущу его более одного раза, даже если я каждый раз выбираю новое имя файла. А именно, похоже, каким-то образом сохраняются изменения/дополнения, сделанные при каждом запуске. Ниже приведен соответствующий код...

    public partial class Form1 : Form
    {
        SqlConnection conn;

        public  void CreateSqlDatabase(string filename)
        {
            string databaseName = 
            System.IO.Path.GetFileNameWithoutExtension(filename);
            conn = new SqlConnection(
              String.Format(

 @"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True"

              ));
            conn.Open();
            using (var command = conn.CreateCommand())
            {
                command.CommandText = 
                 String.Format(

 "CREATE DATABASE {0} ON PRIMARY (NAME={0}, FILENAME='{1}')"

                 , databaseName, filename);

                command.ExecuteNonQuery();
                command.CommandText = 

 String.Format("EXEC sp_detach_db '{0}', 'true'", databaseName);

                command.ExecuteNonQuery();
            }
            conn.Close();            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                CreateSqlDatabase(openFileDialog1.FileName);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            conn.Open();
            SqlCommand comm = conn.CreateCommand();
            comm.CommandText = 

 "create table mytable (id int, name nvarchar(100))";

            comm.ExecuteNonQuery();
            comm.CommandText = 

 "insert into mytable (id,name) values (10,'testing')";

            comm.ExecuteNonQuery();
            comm.CommandText = "select * from mytable";
            SqlDataReader reader = comm.ExecuteReader();

            while (reader.Read())
            {
                textBox1.Text += 

 reader["id"].ToString() + ", " + reader["name"].ToString() + "\r\n";

            }
            conn.Close();

        }
    }

Если я запускаю приложение один раз, оно работает нормально.

Если я запускаю приложение во второй раз и выбираю другое имя файла для базы данных, оно сообщает мне, что «mytable» уже существует.

Если я закомментирую код создания таблицы, он запустится, но запрос на выборку вернет несколько строк, указывающих на несколько вставок (по одной при каждом запуске приложения)

Я просто пытаюсь понять, почему это происходит. Нужно ли мне каждый раз удалять базу данных/таблицу, если я хочу, чтобы приложение вело себя так, как если бы оно создавало базу данных/таблицу с нуля при каждом последующем запуске?


person MrVimes    schedule 26.12.2014    source источник
comment
Похоже, вы всегда подключались к базе данных master, а не к той, которую вы создали. Поэтому, когда вы создаете таблицу, она создается в основной базе данных.   -  person Tien Dinh    schedule 27.12.2014


Ответы (1)


У вас есть начальный каталог «мастер» в строке подключения. Вы уверены, что не создали таблицы в базе данных master вместо вновь созданной базы данных?

После создания и отключения файла базы данных вы можете попробовать изменить свое соединение на:

 SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=c:\xxx\xxx\xxx.mdf");
person Tim Eeckhaut    schedule 26.12.2014
comment
Это было дословно скопировано из другого вопроса о переполнении стека. Существует ли «мастер» где-то еще, кроме файла? Где-то еще в системе? Простите наивный вопрос. - person MrVimes; 27.12.2014
comment
База данных «master» в sqlserver — это системная база данных, содержащая информацию о зарегистрированных базах данных, резервных копиях, выполнении запросов и т. д. - person Tim Eeckhaut; 27.12.2014
comment
Я понимаю. Если я изменю его с «мастер» на имя, указанное для базы данных, это выдаст мне ошибку о сбое входа в систему. Я думаю, было проще и проще использовать sqlite. - person MrVimes; 27.12.2014
comment
@MrVimes Я бы посоветовал вам, в зависимости от того, что вы делаете, LocalDB будет стоить (очень) небольших дополнительных усилий, чтобы заставить его работать правильно, по сравнению с SQLite. Наборы функций совершенно разные. - person dodexahedron; 27.12.2014
comment
Как вы предложили, я повторно подключился с именем файла, указанным в строке подключения, и теперь приложение ведет себя более ожидаемо, и я лучше понимаю, что происходит. спасибо кодмонки - person MrVimes; 27.12.2014
comment
@dodexahedron спасибо. Это потребовало меньше дополнительных усилий, чем я ожидал, и редактирование вопроса codemonkey предоставило код (и понимание), в котором я нуждался. Спасибо за вашу помощь :) - person MrVimes; 27.12.2014