【问题标题】:Upgrading WinForms SQLite Database techniques升级 WinForms SQLite 数据库技术
【发布时间】:2014-09-25 04:57:42
【问题描述】:

我一直在研究数据库的升级过程,特别是那些 SQLite 类型的。

我对程序如何知道这一点感到困惑,“嘿..这个表不存在,让我们创建它吧!”或“嘿,它确实存在,但它落后了三个版本,让我们更新它!”

我的意思是,我可以编写特定于每个表的每个版本的代码(基本上列出了其中应该包含哪些列...),然后将其全部转储到每个表的大量 if 语句或类似的愚蠢的东西中,但这太疯狂了。 -`真的很疯狂。

(我会包含该代码,以便你们指出如何改进,但我已经知道这肯定不是正确的方法吗?)

-数据库升级实际使用了什么技术?

我想详细了解:

a)检查表是否存在的最佳技术是什么?

b)程序如何知道一个表后面有多少个版本?

-这适用于 SQLite 3,用于桌面应用程序。

【问题讨论】:

    标签: c# sql winforms sqlite upgrade


    【解决方案1】:

    一种简单的方法是在您的数据库中创建一个特殊的表。让我们假设这个特殊的表被称为 DBVersion。此表仅包含一行,其中包含一个数字列,其中包含数据库的版本号。最初,此表包含值 0

    现在假设您有一个具有相似架构的 XML 文件

    <?xml version="1.0" standalone="yes"?>
    <DatabaseUpdater>
      <xs:schema id="DatabaseUpdater" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xs:element name="DatabaseUpdater" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="UpdateCMD">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="DBType" type="xs:int" minOccurs="0" />
                    <xs:element name="Version" type="xs:int" minOccurs="0" />
                    <xs:element name="Command" type="xs:string" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:schema>
      <UpdateCMD>
        <DBType>1</DBType>
        <Version>1</Version>
        <Command>CREATE TABLE userTable ......
        </Command>
      </UpdateCMD>
    </DatabaseUpdater>
    

    现在您可以编写读取数据库 DBVersion 表号的代码,然后加载 XML 文件,在 DBVersion 表中搜索版本值高于版本号的命令并执行它们。执行成功后,更新 DBVersion 表中的版本号。 (此处应特别注意避免错误,日志文件是必不可少的)。

    int currentVersion = GetDBVersionNumber();
    
    string scriptFile = "UPGRADE_DB.XML";
    DataSet ds = new DataSet();
    ds.ReadXml(scriptFile, XmlReadMode.ReadSchema);
    
    string filter = "Version > " + currentVersion.ToString();
    string sort = "Version";
    
    DataRow[] rows = ds.Tables[0].Select(filter, sort);
    if (rows.Length == 0)
        return;
    
    try
    {
        using(SQLiteConnection cnn = new SQLiteConnection(.....))
        using(SQLiteCommand cmd = cnn.GetCommand())
        {
            foreach (DataRow dr in rows)
            {
                cmd.CommandText = dr.Field<string>("Command");
                cmd.CommandType = CommandType.Text;
                cmd.ExecuteNonQuery();
                UpdateDBVersionNumber(dr.Field<int>("Version"));
                WriteLog(currentVersion);
            }
        }
    }
    catch(Exception ex)
    {
        WriteLog(ex);
    }
    

    当您需要升级您的数据库时,您只需将另一个“记录”添加到 XML 文件并将其分发给您的客户。应用程序应该能够升级数据库,而无需为此特定目的更改您的代码

    【讨论】:

      【解决方案2】:

      最广泛使用的方式是Android使用的方式:这是用SQLiteOpenHelper class处理的,它在数据库中存储一个版本号(使用PRAGMA user_version,但确切的机制无关紧要)并有onCreate /onUpdate 应用程序处理这些情况的回调。

      您无需检查单个表格;数据库版本号负责处理。 (您可以通过将整个更新放入事务中来保持一切一致。)

      查看the source(尤其是getDatabaseLocked)并实现类似的东西。


      当您有多个旧版本时,处理此问题的典型方法如下:

      if (oldVersion < 2)
      {
          // update everything from version 1 to 2
      }
      if (oldVersion < 3)
      {
          // update everything from version 2 to 3
      }
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多