c# - 插入行后提交到 sqlite

问题描述 投票:0回答:1

我正在编写我的第一个 C# Windows 窗体应用程序,我将其用于个人用途。这是一个适合我的天文摄影爱好的实用应用程序。我不得不多次从存储库中恢复我的代码,只是因为我把事情搞砸了太多。 sqlite 数据库已经很破烂了,我“认为”我可能搞乱了索引。我可以重建它,那里没有我无法重新创建的数据。

代码的逻辑是,在尝试插入之前,我检查是否已将目标记录到数据库中。这是我用来查看是否已经在应用程序中记录了我正在处理的目标的代码..

string connectionString = "Data Source=..\\..\\Astrophotography DataBase\\Astrophotography.db;Version=3;";

public bool QueryATI(string strTargetName, string[] arrEquipment)
{
    using (SQLiteConnection conn = new SQLiteConnection(connectionString))
    {
        conn.Open();
        bool result = false; 
        SQLiteCommand command =
             new SQLiteCommand("SELECT ATI_TargetName, ATI_Telescope_Lens_Used FROM Astro_Target_Imaged WHERE ATI_TargetName = @Target", conn);
        command.Parameters.Add(new SQLiteParameter("@Target", strTargetName));
        using (SQLiteDataReader TargetReader = command.ExecuteReader())
        {
            int i = 0;
            
            if (TargetReader.HasRows)
            {
             // It is very possible  a target has been imaged more than once with different
             // equipment or focal lengths.  This checks to see what has been recorded of 
             // any of them, and if this one is not recorded.  It will be added.
                {
                    string strTelescope = TargetReader["ATI_Telescope_Lens_Used"].ToString();
                    string strArrayValue = arrEquipment[i].ToString();
                    if (strTelescope == arrEquipment[i])
                    {
                        result = true;
                        conn.Clone();
                        return result;
                    }
                    i++;
                }
            }
            result = false;
            conn.Clone();
            return result;
        }
          
       
        result = false;
        conn.Clone();
        return result;
    }
   

}

如果我发现目标尚未存储在数据库中,则我使用下面的代码将其插入。

       public void BuildATI(string strTargetName, string strMount, string strICamera, string strTelescope, string strFilter, string strGuidCamera, string strGuideScope)
       {
           using (SQLiteConnection conn = new SQLiteConnection(connectionString))
           {
               conn.Open();
               bool result = false;
               string strInsert = ("INSERT INTO Astro_Target_Imaged");
               string strColumns = "(ATI_TargetName, ATI_Mount_Used, ATI_Image_Camera, ATI_Telescope_Lens_Used, ATI_Filter, ATI_Guide_Camera, ATI_Guide_Scope_Used)";
               string strValues = "VALUES (@Target, @Mount, @ICamera, @Telescope, @Filter, @GCamera, @GScope)";
               string strQuery = strInsert + strColumns + strValues;   
               SQLiteCommand command =
                    new SQLiteCommand(strQuery, conn);
               command.Parameters.Add(new SQLiteParameter("@Target", strTargetName));
               command.Parameters.Add(new SQLiteParameter("@Mount", strMount));
               command.Parameters.Add(new SQLiteParameter("@ICamera", strICamera));
               command.Parameters.Add(new SQLiteParameter("@Telescope", strTelescope));
               command.Parameters.Add(new SQLiteParameter("@Filter", strFilter));
               command.Parameters.Add(new SQLiteParameter("@GCamera", strGuidCamera));
               command.Parameters.Add(new SQLiteParameter("@GScope", strGuideScope));
               //.FirstOrDefault();

               try
               {
                   command.ExecuteNonQuery();
                   //conn.Commit();
               }
               catch (Exception ex)
               {
                   throw new Exception(ex.Message);
               }
                           
               conn.Clone();
           }


       }
   }

我的问题是,无论出于什么原因,在我执行插入操作后,我已经在调试中完成了操作并且没有收到任何错误。插入不会引发异常。但是当我在 SqliteStudio 中对其进行查询时,我没有看到它。因此,然后我重新运行相同的数据,通过该数据通过完全相同的检查代码,其中 if 语句表明它有行。但是,当我尝试访问表中的列时。它抛出异常,未找到任何行。这就是为什么我认为我破坏了数据库。

所以,我的问题是。目前,我在插入语句之后的代码中没有提交语句。我曾经使用过的所有其他类型的数据库(oracle、mysql、sql server)。你总是承诺。拍摄,当我使用 sqlitestudio 时。我必须做承诺。这就是我认为我破坏索引的原因之一。

所以,我的问题是。在数据库中建立索引?针对 sqlite 的提交的语法是什么?

任何帮助将不胜感激。

sqlite c#-3.0
1个回答
0
投票

您尚未关闭连接!

打开方法(SQLLiteCONnection)
注意:如果 SQLiteConnection 超出范围,它代表的连接不会自动关闭。因此,您必须通过调用 Close 显式关闭连接。

如果您不

.Close();
连接,那么它会保持打开状态,当它最终超时或从服务器关闭时,该连接中任何未提交的更改都将丢失。

在您的代码中,您错误地调用了

.Clone()
而不是
.Close()

    result = true;
    conn.Clone();
    return result;

对于读取操作,您不会真正注意到这一点,但对于写入操作,您的更改将永远不会被提交。


正如这里所解释的:事务sqlite?在 C#SQLite.org

在 V3 中,

SQLiteConnection.Commit()
已被删除,连接预计在 AutoCommit 模式下运行。不过,我们鼓励您使用事务范围和事务。

AutoCommit 模式下,会在连接的生命周期内创建一个事务,但仅当使用调用 SQLiteConnection.Close(); 有意 关闭

 连接时才会
提交

要开始使用事务,您的代码应如下所示:

   public void BuildATI(string strTargetName, string strMount, string strICamera, string strTelescope, string strFilter, string strGuidCamera, string strGuideScope)
   {
       using (SQLiteConnection conn = new SQLiteConnection(connectionString))
       using (var trans = conn.BeginTransaction())
       {
           conn.Open(); // dont forget to close!
           bool result = false;
           string strInsert = ("INSERT INTO Astro_Target_Imaged");
           string strColumns = "(ATI_TargetName, ATI_Mount_Used, ATI_Image_Camera, ATI_Telescope_Lens_Used, ATI_Filter, ATI_Guide_Camera, ATI_Guide_Scope_Used)";
           string strValues = "VALUES (@Target, @Mount, @ICamera, @Telescope, @Filter, @GCamera, @GScope)";
           string strQuery = strInsert + strColumns + strValues;   
           SQLiteCommand command =
                new SQLiteCommand(strQuery, conn);
           command.Parameters.Add(new SQLiteParameter("@Target", strTargetName));
           command.Parameters.Add(new SQLiteParameter("@Mount", strMount));
           command.Parameters.Add(new SQLiteParameter("@ICamera", strICamera));
           command.Parameters.Add(new SQLiteParameter("@Telescope", strTelescope));
           command.Parameters.Add(new SQLiteParameter("@Filter", strFilter));
           command.Parameters.Add(new SQLiteParameter("@GCamera", strGuidCamera));
           command.Parameters.Add(new SQLiteParameter("@GScope", strGuideScope));
           //.FirstOrDefault();

           try
           {
               command.ExecuteNonQuery();
               trans.Commit();
           }
           catch (Exception ex)
           {
               // TODO:  for more complex logic you might consider rollback here
               // trans.Rollback();

               // NOTE: SQLiteConnection supports Rollback too!
               conn.Rollback()
               throw new Exception(ex.Message);
           }
                       
           conn.Close(); // explicitly close any connection you open!
       }
   }
© www.soinside.com 2019 - 2024. All rights reserved.