2013-03-14 144 views
0

这将是一个漫长的问题 - 我一直花费一整天的时间来解决这个问题,所以也许你们可以帮忙!我试图通过允许数据库结构在呈现新结构(采用XML格式)时进行更改来对我的数据库应用程序进行面向未来的验证。XML到DataTable - 返回空白单元格

目前我正在管理将数据库结构导出到XML中。请参见下面的工作代码:

public void generateXMLStructureCompactDB(string fileName) 
    { 
     DataTable table = new DataTable(); 
     int position; 
     FileStream fsWrite; 
     StreamWriter sw; 

     string version = "1.1.1.0"; 
     table.Columns.Add("TableName", Type.GetType("System.String")); 
     table.Columns.Add("ColName", Type.GetType("System.String")); 
     table.Columns.Add("Position", Type.GetType("System.Int32")); 
     table.Columns.Add("DataType", Type.GetType("System.String")); 
     table.Columns.Add("MaximumLength", Type.GetType("System.Int32")); 
     table.Columns.Add("Precision", Type.GetType("System.Int32")); 
     table.Columns.Add("Scale", Type.GetType("System.Int32")); 
     table.Columns.Add("Nullable", Type.GetType("System.Boolean")); 
     table.Columns.Add("Identity", Type.GetType("System.Boolean")); 
     table.Columns.Add("IdentitySeed", Type.GetType("System.Int32")); 
     table.Columns.Add("IdentityIncrement", Type.GetType("System.Int32")); 

     string sql = "select Table_Name, Column_Name, Ordinal_Position, Data_Type, " + 
      "Character_Maximum_Length, Numeric_Precision, Numeric_Scale, Is_Nullable, " + 
      "case when AutoInc_Seed is null then 0 else 1 end as IS_IDENTITY, " + 
      "AutoInc_Seed, AutoInc_Increment from information_schema.columns"; 
     runSQL(sql, out table); 

     if (File.Exists(fileName)) 
      File.Delete(fileName); 

     fsWrite = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); 
     sw = new StreamWriter(fsWrite, Encoding.ASCII); 

     XmlWriter writer = new XmlTextWriter(sw); 
     writer.WriteStartDocument(false); 
     writer.WriteRaw(Environment.NewLine); 
     writer.WriteComment("DBVersion=" + DBVersion + ", created=" + DateTime.Now.ToString()); 
     writer.WriteRaw(Environment.NewLine); 

     writer.Close(); 
     sw.Close(); 
     fsWrite.Close(); 

     fsWrite = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); 
     sw = new StreamWriter(fsWrite, Encoding.ASCII); 

     DataTable indexes = new DataTable(); 
     indexes.Columns.Add("TableName", Type.GetType("System.String")); 
     indexes.Columns.Add("Schema", Type.GetType("System.String")); 
     indexes.Columns.Add("IndexName", Type.GetType("System.String")); 
     indexes.Columns.Add("Clustered", Type.GetType("System.Boolean")); 
     indexes.Columns.Add("Unique", Type.GetType("System.Boolean")); 
     indexes.Columns.Add("IndexColName", Type.GetType("System.String")); 
     sql = "select Table_Name, Table_Schema, Index_Name, [Clustered], [Unique], " + 
      "Column_Name from information_schema.indexes"; 
     runSQL(sql, out indexes); 

     table.TableName = "Tables"; 
     indexes.TableName = "Indexes"; 

     table.WriteXml(sw); 
     sw.WriteLine(""); 
     indexes.WriteXml(sw); 
     sw.Close(); 
     fsWrite.Close(); 
    } 

下面是我的生成的XML文件(实际版本是这样大,但我已经剥离下来到一个表和一个索引):

<?xml version="1.0" encoding="us-ascii" standalone="no"?> 
<!--DBVersion=1.0.0.0, created=14/03/2013 13:18:20--> 
<DocumentElement> 
    <Tables> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <COLUMN_NAME>ContactLogId</COLUMN_NAME> 
    <ORDINAL_POSITION>1</ORDINAL_POSITION> 
    <DATA_TYPE>int</DATA_TYPE> 
    <NUMERIC_PRECISION>10</NUMERIC_PRECISION> 
    <IS_NULLABLE>NO</IS_NULLABLE> 
    <IS_IDENTITY>1</IS_IDENTITY> 
    <AUTOINC_SEED>1</AUTOINC_SEED> 
    <AUTOINC_INCREMENT>1</AUTOINC_INCREMENT> 
    </Tables> 
    <Tables> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <COLUMN_NAME>CustomerId</COLUMN_NAME> 
    <ORDINAL_POSITION>2</ORDINAL_POSITION> 
    <DATA_TYPE>int</DATA_TYPE> 
    <NUMERIC_PRECISION>10</NUMERIC_PRECISION> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <IS_IDENTITY>0</IS_IDENTITY> 
    </Tables> 
    <Tables> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <COLUMN_NAME>ContactDate</COLUMN_NAME> 
    <ORDINAL_POSITION>3</ORDINAL_POSITION> 
    <DATA_TYPE>datetime</DATA_TYPE> 
    <NUMERIC_PRECISION>23</NUMERIC_PRECISION> 
    <NUMERIC_SCALE>3</NUMERIC_SCALE> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <IS_IDENTITY>0</IS_IDENTITY> 
    </Tables> 
    <Tables> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <COLUMN_NAME>ContactTypeId</COLUMN_NAME> 
    <ORDINAL_POSITION>4</ORDINAL_POSITION> 
    <DATA_TYPE>int</DATA_TYPE> 
    <NUMERIC_PRECISION>10</NUMERIC_PRECISION> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <IS_IDENTITY>0</IS_IDENTITY> 
    </Tables> 
    <Tables> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <COLUMN_NAME>AuditText</COLUMN_NAME> 
    <ORDINAL_POSITION>5</ORDINAL_POSITION> 
    <DATA_TYPE>nvarchar</DATA_TYPE> 
    <CHARACTER_MAXIMUM_LENGTH>2048</CHARACTER_MAXIMUM_LENGTH> 
    <IS_NULLABLE>YES</IS_NULLABLE> 
    <IS_IDENTITY>0</IS_IDENTITY> 
    </Tables> 
    <Tables> 
    <TABLE_NAME>ContactType</TABLE_NAME> 
    <COLUMN_NAME>ContactTypeId</COLUMN_NAME> 
    <ORDINAL_POSITION>1</ORDINAL_POSITION> 
    <DATA_TYPE>int</DATA_TYPE> 
    <NUMERIC_PRECISION>10</NUMERIC_PRECISION> 
    <IS_NULLABLE>NO</IS_NULLABLE> 
    <IS_IDENTITY>1</IS_IDENTITY> 
    <AUTOINC_SEED>1</AUTOINC_SEED> 
    <AUTOINC_INCREMENT>1</AUTOINC_INCREMENT> 
    </Tables> 
</DocumentElement> 
<DocumentElement> 
    <Indexes> 
    <TABLE_NAME>ContactLog</TABLE_NAME> 
    <INDEX_NAME>PK_ContactLog</INDEX_NAME> 
    <CLUSTERED>false</CLUSTERED> 
    <UNIQUE>true</UNIQUE> 
    <COLUMN_NAME>ContactLogId</COLUMN_NAME> 
    </Indexes> 
</DocumentElement> 

现在这是读取XML文件的代码的一部分。 XML文件包含两个独立表的列 - tables(实际上是列的列表)和indexes - 索引列表。它根据<DocumentElement>的位置将文件拆分为两部分,然后将这两个XML元素放入两个单独的表中。请参见下面的代码:

static bool VerifyStructure() 
    { 
     FileStream fsWrite; 
     int i; 
     StreamWriter sw; 
     string DBStructureVersion = "0.0.0.0"; 
     string xmlFile; 
     string s; 
     string tmp = Environment.GetEnvironmentVariable("TEMP"); 
     if (tmp == "") 
      tmp = Environment.GetEnvironmentVariable("SystemDrive"); 
     try 
     { 
      xmlFile = tmp + @"\dbStructure.xml"; 
      if (File.Exists(xmlFile)) 
       File.Delete(xmlFile); 

      fsWrite = new FileStream(xmlFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); 
      sw = new StreamWriter(fsWrite, Encoding.ASCII); 
      sw.Write(syntos.Properties.Resources.dbStructure); 
      sw.Close(); 
      fsWrite.Close(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error reading structure xml file: " + ex.Message); 
      return false; 
     } 
     if (!File.Exists(xmlFile)) 
     { 
      MessageBox.Show("XML Structure file '" + xmlFile + "' does not exist."); 
      return false; 
     } 
     StreamReader sr = new StreamReader(xmlFile); 
     s = sr.ReadLine(); 
     while (s != null) 
     { 
      if (s.Contains("DBVersion=")) 
      { 
       i = s.IndexOf("DBVersion="); 
       DBStructureVersion = s.Substring(i + 10); 
       i = DBStructureVersion.IndexOf(","); 
       DBStructureVersion = DBStructureVersion.Substring(0, i); 
       break; 
      } 
      s = sr.ReadLine(); 
     } 
     sr.Close(); 

     // Split the remaining XML file into two: table datatable file and index datatable file 
     // Write out to file1 all the table information and to file2 all the index information 
     string file1path; 
     string file2path; 

     try 
     { 
      file1path = tmp + @"\tables.xml"; 
      file2path = tmp + @"\indexes.xml"; 
      if (File.Exists(file1path)) 
       File.Delete(file1path); 

      if (File.Exists(file2path)) 
       File.Delete(file2path); 

      FileStream fsw1 = new FileStream(file1path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); 
      FileStream fsw2 = new FileStream(file2path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); 
      StreamWriter sw1 = new StreamWriter(fsw1, Encoding.ASCII); 
      StreamWriter sw2 = new StreamWriter(fsw2, Encoding.ASCII); 

      // Create a file containing just the table/column definitions 
      sr = new StreamReader(xmlFile); 
      s = sr.ReadToEnd(); 
      sr.Close(); 

      i = s.IndexOf("<DocumentElement>"); 
      s = s.Substring(i); 
      i = s.IndexOf("</DocumentElement>"); 
      s = s.Substring(0, i + 18); 
      sw1.Write(s); 
      sw1.Close(); 
      fsw1.Close(); 

      // Create a file containing the index column definitions 
      sr = new StreamReader(xmlFile); 
      s = sr.ReadToEnd(); 
      sr.Close(); 

      i = s.IndexOf("</DocumentElement>"); 
      s = s.Substring(i + 18); 
      sw2.Write(s); 
      sw2.Close(); 
      fsw2.Close(); 
      sr.Close(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error producing the table and index XML file. " + ex.Message); 
      return false; 
     } 

     DataTable table = new DataTable(); 
     table.Columns.Add("TableName", Type.GetType("System.String")); 
     table.Columns.Add("ColName", Type.GetType("System.String")); 
     table.Columns.Add("Position", Type.GetType("System.Int32")); 
     table.Columns.Add("DataType", Type.GetType("System.String")); 
     table.Columns.Add("MaximumLength", Type.GetType("System.Int32")); 
     table.Columns.Add("Precision", Type.GetType("System.Int32")); 
     table.Columns.Add("Scale", Type.GetType("System.Int32")); 
     table.Columns.Add("Nullable", Type.GetType("System.Boolean")); 
     table.Columns.Add("Identity", Type.GetType("System.Boolean")); 
     table.Columns.Add("IdentitySeed", Type.GetType("System.Int32")); 
     table.Columns.Add("IdentityIncrement", Type.GetType("System.Int32")); 
     table.TableName = "Tables"; 

     DataTable indexes = new DataTable(); 
     indexes.Columns.Add("TableName", Type.GetType("System.String")); 
     indexes.Columns.Add("Schema", Type.GetType("System.String")); 
     indexes.Columns.Add("IndexName", Type.GetType("System.String")); 
     indexes.Columns.Add("Clustered", Type.GetType("System.Boolean")); 
     indexes.Columns.Add("Unique", Type.GetType("System.Boolean")); 
     indexes.Columns.Add("IndexColName", Type.GetType("System.String")); 
     indexes.TableName = "Indexes"; 

     // Read in the XML for the table/columns 
     sr = new StreamReader(file1path); 
     table.ReadXml(sr); 
     sr.Close(); 
     if (table.Rows.Count == 0) 
     { 
      MessageBox.Show("No loadable table rows found in XML file"); 
      sw.Close(); 
      fsWrite.Close(); 
      return false; 
     } 
     sr = new StreamReader(file2path); 
     indexes.ReadXml(sr); 
     sr.Close(); 
     if (indexes.Rows.Count == 0) 
     { 
      MessageBox.Show("No loadable index rows found in XML file"); 
      sw.Close(); 
      fsWrite.Close(); 
      return false; 
     } 
     DbFunctions.BackupDatabase(); 
     bool success1 = CreateTempTables(table); 
     return true; 
    } 

通过使用断点和调试语句,我可以看到表被填入了正确的行数和列的 - 但所有这些都为空。只是空的细胞。我已经习惯了table.Rows.Count来查看该表中实际上有行。

如果有人能够看到我是否在这里的正确线条,我会永远感激!在此先感谢:)

编辑: 我测试了这与一个不同的XML表,它的工作原理。我生成XML文件的方式肯定有问题,但是我看不到。

我应尽快因为它允许我加入悬赏这一问题;)

摘要的问题:当由系统(第一码块)产生的XML文件被导入到程序再次(第三个代码块),行和列都存在,但所有单元都是空白的。

回答