2016-11-15 50 views
0

我一直在网上寻找答案,但还没有发现任何东西。我有一个小的控制台应用程序,我试图插入一些数据到SQL Server数据库(.mdf数据库文件),一切都运行没有错误,但当我在服务器资源管理器事实后打开数据库时,数据不存在。无法获取数据提交到SQL Server

这是代码:

using (TransactionScope scope = new TransactionScope()) 
{ 
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["FrameBudgetDB"].ToString())) 
    { 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = conn; 

     conn.Open(); 

     cmd.CommandText = string.Format("SELECT TOP 1 category_id FROM businesses WHERE '{0}' LIKE CONCAT('%',description,'%')", transDescription.Replace("'", "''")); 

     SqlDataReader reader = cmd.ExecuteReader(); 

     try 
     { 
      if (reader.HasRows) 
      { 
       while (reader.Read()) 
       { 
        categoryId = (int)reader[0]; 
       } 
      } 
      else 
      { 
       categoryId = 44; // Unknown 
      } 
     } 
     finally 
     { 
      reader.Close(); 
     } 

     // Get Transaction Type 
     int transTypeId = 0; 
     cmd.CommandText = string.Format("SELECT trans_type_id FROM transaction_types WHERE description = '{0}'", transType); 

     reader = cmd.ExecuteReader(); 

     try 
     { 
      if (reader.HasRows) 
      { 
       while (reader.Read()) 
       { 
        transTypeId = (int)reader[0]; 
       } 
      } 
     } 
     finally 
     { 
      reader.Close(); 
     } 

     SqlTransaction trans = conn.BeginTransaction("InsertTransactiolns"); 

     try 
     { 
      cmd.Transaction = trans; 
      cmd.CommandText = string.Format(
           "BEGIN " + 
             "IF NOT EXISTS(SELECT * FROM transactions " + 
                    "WHERE transaction_date = '{0}' " + 
                    "AND description = '{1}' " + 
                    "AND trans_type_id = {2} " + 
                    "AND amount = {3} " + 
                    "AND(category_id = {5} OR previous_category_id = {5})) " + 
            "BEGIN " + 
              "INSERT INTO transactions(transaction_date, description, trans_type_id, import_date, category_id, amount) " + 
              "VALUES('{0}', '{1}', {2}, '{4}', {5}, {3}) " + 
            "END " + 
           "END", transDate, transDescription.Replace("'", "''"), transTypeId, amount, DateTime.Now, categoryId); 

      rowsInserted = rowsInserted + cmd.ExecuteNonQuery(); 
      trans.Commit(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 

      try 
      { 
       trans.Rollback(); 
      } 
      catch (Exception e2) 
      { 
       Console.WriteLine(e2.Message); 
      } 
     }           
    } 
} 

数据库连接字符串是:

<connectionStrings> 
    <add name="FrameBudgetDB" 
     connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|FrameBudget.mdf;Integrated Security=True;Connect Timeout=30" 
     providerName="System.Data.SqlClient" /> 
</connectionStrings> 

和数据目录是:

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\FrameBudget\")); 
+0

检查此问题http://stackoverflow.com/questions/17147249/why-saving-changes-to -a-database-failures – Steve

+0

有趣的是,即使我明确地设置了数据目录,并且当我通过应用程序进行调试并查看连接属性时,数据库显示为位于ProgramData中的正确数据库? – devonuto

+0

并在服务器浏览器中的连接? – Steve

回答

1

真的不清楚为什么你TransactionScope实例和对BeginTransaction的调用。我只会使用其中的一个。但是这条线

using (TransactionScope scope = new TransactionScope()) 
{ 
    ... 

需要成功的情况下完成与

scope.Complete(); 
} 

没有调用完成,退出使用块意味着回滚。
我会与呼叫删除块

SqlTransaction trans = conn.BeginTransaction("InsertTransactiolns"); 

,相对回滚或提交调用只留下TransactionScope的实例(简单了很多处理)。

作为一个侧面说明。您的代码易受Sql注入攻击。该string.Format是一种字符串连接的形式,我们都知道nasty things that can happen与字符串连接方法来建立sql查询

+0

是的,我认为这可能会让人困惑。事实之后,我在SqlTransaction中添加了,因为我认为它可能会起作用。以前我只使用范围,而且我也使用了cmd.AddParameterWithValue()。对参数化字符串的更改是为了能够抓取SQL并直接在数据库上运行它来测试它是否正常工作。 但你是正确的,我错过了scope.Complete()调用。 正如你在这里看到的,我早些时候使用它,但不是在这里:https://github.com/devonuto/VSApplications/blob/master/FrameBudget/FrameBudget/Program.cs – devonuto

+0

我会再次尝试,一旦我回家,但我怀疑缺失的线是问题。 – devonuto

+0

好吧,祝你好运,晚安(至少对我来说) – Steve