2016-02-09 4 views
5

Вопрос начинающего - пожалуйста, я могу запросить совет по созданию файлов локальной базы данных программно во время выполнения. Я хочу, чтобы позже можно было переименовать, удалить их и т. Д. С помощью проводника Windows так же, как и для текста и других файлов, и скопировать их на другие компьютеры.Создание локальной базы данных во время выполнения с Visual Studio

Это приложение Visual Studio Community 15 с C#, установленное SQL Server Data Tools 14.0.50616.0. Компьютер имеет Microsoft SQL Server 2014.

Для примера я удалил лишние части моей программы, чтобы оставить код ниже, который использует форму приложения Windows с 3-мя кнопками (btnCreateDb, btnDeleteDb и btnDoesDbExist) и выпадающий список cbxDb для имени базы данных. Он создает базы данных в существующей папке C:\DbTemp.

Он, по-видимому, создаст и удалит новую базу данных и сделает файлы, например mydb1.mdf, и mydb1.ldf в папке и укажет, что они существуют. Однако, если я удалю два файла с помощью проводника, он выдает исключение, если делается попытка удалить или создать базу данных; и btnDoesDbExist показывает, что он все еще существует.

Почему база данных по-прежнему существует, когда файлы были удалены проводником Windows? Код под btnDoesDatabaseExist не относится к пути файлов, поэтому он должен видеть что-то еще, но где? Является ли это правильным способом для пользователя программы создавать, удалять и обнаруживать эти базы данных?

using System; 
using System.Data; 
using System.Windows.Forms; 

//my additions 
using System.Data.SqlClient; 

namespace DataProg15 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public static string form1ConnectionString = "Data Source = (LocalDB)\\MSSQLLocalDB; Integrated Security = True; Connect Timeout = 30; "; 
    private string form1DatabasePath = "C:\\DbTemp"; 

    private void btnCreateDb_Click(object sender, EventArgs e) 
    { 
     string nameToCreate = cbxDb.Text; 
     SqlConnection myConn = new SqlConnection(form1ConnectionString); 

     string str = "CREATE DATABASE " +nameToCreate+ " ON PRIMARY " + 
      "(NAME = " +nameToCreate+ "_Data, " + 
      "FILENAME = '" +form1DatabasePath+ "\\" +nameToCreate+ ".mdf', " + 
      "SIZE = 4MB, MAXSIZE = 10MB, FILEGROWTH = 10%) " + 
      "LOG ON (NAME = " +nameToCreate+ "_Log, " + 
      "FILENAME = '" +form1DatabasePath+ "\\" +nameToCreate+ ".ldf', " + 
      "SIZE = 1MB, " + 
      "MAXSIZE = 5MB, " + 
      "FILEGROWTH = 10%)"; 

     SqlCommand myCommand = new SqlCommand(str, myConn); 

     try 
     { 
      myConn.Open(); 
      myCommand.ExecuteNonQuery(); 
      MessageBox.Show("DataBase '" + nameToCreate + "' was created successfully"); 
     } 
     catch (System.Exception ex) 
     { 
      MessageBox.Show("Exception in CreateDatabase " + ex.ToString(), "Exception in CreateDatabase", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 
     finally 
     { 
      if (myConn.State == ConnectionState.Open) 
      { 
       myConn.Close(); 
      } 
     } 
    } 


    private void btnDeleteDb_Click(object sender, EventArgs e) 
    { 
     string nameToDelete = cbxDb.Text; 
     string myConnectionString = form1ConnectionString + "AttachDBFileName = " + form1DatabasePath + "\\" + nameToDelete + ".mdf "; 
     string str = "USE MASTER DROP DATABASE " + nameToDelete; 

      SqlConnection myConn = new SqlConnection(myConnectionString); 
      SqlCommand myCommand = new SqlCommand(str, myConn); 
      myConn.Open(); 

      try 
      { 
       myCommand.ExecuteNonQuery(); 
       MessageBox.Show("DataBase '" + nameToDelete + "' was deleted successfully"); 

      } 
      catch (System.Exception ex) 
      { 
       MessageBox.Show(ex.ToString(), "Exception in DeleteDatabase '" +nameToDelete+ "'", MessageBoxButtons.OK, MessageBoxIcon.Information); 
      } 
      finally 
      { 
       if (myConn.State == ConnectionState.Open) 
       { 
        myConn.Close(); 
       } 
      } 
    } 

    private void btnDoesDbExist_Click(object sender, EventArgs e) 
    { 
     string nameToTest = cbxDb.Text; 
     using (var connection = new SqlConnection(form1ConnectionString)) 
     { 
      using (var command = new SqlCommand(string.Format(
        "SELECT db_id('" +nameToTest+ "')", nameToTest), connection)) 
      { 
       connection.Open(); 

       if ((command.ExecuteScalar() != DBNull.Value)) 
       { 
        MessageBox.Show("DataBase '" +nameToTest+ "' exists"); 
       } 
       else 
       { 
        MessageBox.Show("Database '" +nameToTest+ "' does not exist"); 
       } 
      } 
     } 

    } 
} 

}

Спасибо всем за ответы, и ваша проблема очень ценится.

Теперь я понимаю, что я использую неправильную базу данных, поэтому вместо этого я попытался использовать SQL Server Compact. Удалили, загрузили снова и переустановили SQL Server Compact, включая SP1. Загрузили и установили SQL Server Compact/SQLite Toolbox от https://visualstudiogallery.msdn.microsoft.com/0e313dfd-be80-4afb-b5e9-6e74d369f7a1. Но Visual Studio на протяжении всего показала ошибку, когда я печатаю using System.Data.SqlServerCe. Кроме того, когда я набираю SqlCeEngine или SqlCecommand, предположим по той же причине.

В Visual Studio SQL Server Data Tools и SQL Server Compact & SQLite Toolbox показаны как установленные продукты, но не SQL Server Compact. Нужно ли устанавливать это в Visual Studio, и если да, то как это делается?

+0

Вы не должны взаимодействовать с файлами данных. Если вы действительно хотите так поступать, вам нужно использовать «отсоединить» и «прикрепить». На данный момент ваш localdb sqlserver знает о базе данных, но не может найти файлы данных. –

+0

Это может быть чрезмерным в вашем сценарии, но рассмотрели ли вы использование [Первичная миграция схемы первого кода] (https://msdn.microsoft.com/en-gb/data/jj591621.aspx)? –

+1

Sql Server - сложная система. Когда вы создаете базу данных, вы не добавляете только пару имен файлов, а также много информации о системе и конфигурации. Эти данные хранятся во внутренних базах данных (модель, мастер, temp и т. Д.). Использование проводника Windows для удаления этих файлов. Установка Sql Server в неустойчивом состоянии, поскольку внутренняя информация все еще существует, кроме файлов. Если вам нужна такая свобода, выберите другую систему баз данных (основанную на файле), такую ​​как SQLite, Sql Server Compact и даже MS-Access. – Steve

ответ

0

SQL Server не позволит вам удалять физические файлы базы данных, если эта база данных активна - КОГДА-ЛИБО. Единственное, что вы когда-либо могли бы сделать, это если база данных DETACHED (как упоминалось ранее)

Так что я подозреваю, что что-то ваше сообщение нам не совсем верно?

Я бы изменил вашу логику «проверить базу данных», чтобы быть;

выберите * из sys.databases где имя = «имя_базы_данных»

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

+0

Спасибо. Ответы и дальнейшее чтение подсказывают, что я должен использовать базу данных, которая существует только в локальном файле, поэтому я пытаюсь использовать SQL Server Compact вместо этого, но все еще испытываю трудности, как описано в приведенном выше правиле. – egginstone

2

В Solution Explorer под References, отметьте, что System.Data.SqlServerCe указан.Если нет, щелкните правой кнопкой мыши по References, затем Add Reference ->Browse и выберите файл System.Data.SqlServerCe.dll, возможно, в C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Desktop. System.Data.SqlServerCe должно теперь отображаться под References.

Программа работает, и это намного проще. Спасибо всем за помощь.

using System; 
using System.Data; 
using System.Windows.Forms; 
//my additions 
using System.Data.SqlServerCe; 
using System.IO; 

namespace DataProg15 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     public static string form1DatabasePath = "C:\\DbTemp\\dbtemp1.sdf"; 
     public static string form1ConnectionString = "Data Source = " +form1DatabasePath; 

     private void btnCreateDb_Click(object sender, EventArgs e) 
     { 
       SqlCeEngine engine = new SqlCeEngine(form1ConnectionString); 
      try 
      { 
       engine.CreateDatabase(); 
       MessageBox.Show("DataBase '" +form1DatabasePath+ "' was created successfully"); 
      } 
      catch (System.Exception ex) 
      { 
       MessageBox.Show("Exception in CreateDatabase " + ex.ToString(), "Exception in CreateDatabase", MessageBoxButtons.OK, MessageBoxIcon.Information); 
      } 
      finally 
      { 
       engine.Dispose(); 
      } 
     } 

     private void btnDeleteDb_Click(object sender, EventArgs e) 
     { 
      if (File.Exists(form1DatabasePath)) 
      { 
       try 
       { 
        File.Delete(form1DatabasePath); 
        MessageBox.Show("DataBase '" +form1DatabasePath+ "' was deleted successfully"); 
       } 
       catch (System.Exception ex) 
       { 
        MessageBox.Show(ex.ToString(), "Exception in DeleteDatabase '" +form1DatabasePath+ "'", MessageBoxButtons.OK, MessageBoxIcon.Information); 
       } 
      } 
     } 

     private void btnDoesDbExist_Click(object sender, EventArgs e) 
     { 
      if (File.Exists(form1DatabasePath)) 
      { 
        MessageBox.Show("DataBase '" +form1DatabasePath+ "' exists"); 
      } 
      else 
      { 
        MessageBox.Show("DataBase '" +form1DatabasePath+ "' does not exist"); 
      } 
     } 
    } 
} 
Смежные вопросы