在c#中生成包含百万条记录的xml文件的最快方法

时间:2014-02-07 18:14:26

标签: c# xml oracle odp.net

我在VS2008中创建了一个Windows应用程序,我的要求是从一个获取一百万条记录的表中生成一个xml文件。有关最佳和最快方法的任何指示?

同样最好的方法是什么?

选项1:在Oracle中创建一个clob并在代码中获取它 Oracle SP:

CREATE OR REPLACE PROCEDURE GetBP (BP OUT XMLTYPE) AS
BEGIN

SELECT XMLRoot(
     XMLElement("MASTER_TABLE",
       XMLAgg(XMLElement("PARTNER",

           XMLForest(PARTNER_NO  as "PARTNER_NO"
                    ,'0001' as "ID" )))
   ), VERSION '1.0', STANDALONE YES) AS "RESULT"
INTO BP
from TABLE1
where YEAR LIKE '%2011-2012%';

END GetBP ;
/

C#代码:

private void CreateXML() 
    {
        string oradb = "Data Source=(DESCRIPTION="
        + "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=XPS)(PORT=1226)))"
        + "(CONNECT_DATA=(SERVICE_NAME=DBP0)));"
        + "User Id=scoot;Password=tiger;";

        OracleConnection conn = new OracleConnection(); 
        conn.ConnectionString = oradb;
        conn.Open();

        OracleCommand cmd = new OracleCommand();
        cmd.Connection = conn;
        OracleDataAdapter da = new OracleDataAdapter();
        cmd.Parameters.Add("BP", OracleDbType.XmlType).Direction = ParameterDirection.Output;
        cmd.CommandText = "GetBP";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.ExecuteNonQuery();
        string doc = ((Oracle.DataAccess.Types.OracleXmlType)(cmd.Parameters["BP"].Value)).Value;
        File.WriteAllText("C:/Test/BookInfo.xml", doc);
        cmd.Dispose();
        conn.Dispose();
    }

选项2:首先获取记录,然后使用XML Writer在c#中构建xml 选项3:批量获取记录并构建xml 我的桌子T1

  

PARTNER_NO姓名
  00001 Archie
  00034威廉姆斯
  00046马克
  00052贝蒂

这就是我的XML的外观:
enter image description here

请举例说明最佳方法。我试图用类似的方法搜索示例。找不到一个。选项1需要相当长的时间才能获取记录。

已修改

尝试选项2后,我收到'ContextSwitchDeadlock'例外。
我也尝试将IDataReader更改为OracleDataReader以增加fetchsize,但它没有帮助。请指点。以下是我的代码:

cmd.CommandText = "SELECT PARTNER_NO FROM T1 WHERE YEAR LIKE '%2011-2012%'";  
XmlWriter myWriter = XmlWriter.Create("C:/Test/BookInfo.xml")  
myWriter.WriteStartDocument(true); 
using(OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))  
  {  
    reader.FetchSize = reader.RowSize * 5000;  
    myWriter.WriteStartElement("master_table");
    while(reader.Read())
      {  
         myWriter.WriteStartElement("partner");  
         myWriter.WriteElementString("partner_no", reader[0].ToString());  
         myWriter.WriteElementString("id","0008");  
         myWriter.WriteEndElement();  
      }  
 }  

 myWriter.WriteEndDocument();  
 myWriter.Flush();  
 myWriter.Close();  
 cmd.Dispose()  

2 个答案:

答案 0 :(得分:0)

您可以尝试最直观的方法,迭代IDataReader并随时写入XmlWriter

我不知道这是否是最快的方式,但它应该是最有效的内存,并且您不需要创建任何类型的批次:

using (IDataReader reader = simpleSelectCommand.ExecuteReader())
{
    while (reader.Read())
    {
        myWriter.WriteStartElement("PARTNER");
        // write subnodes for this record
        myWriter.WriteEndElement();
    }
}

这不应该花费你很多时间,而且可能对你来说足够快。

答案 1 :(得分:0)

XML总是占用大量空间,因此需要很长时间才能从服务器传输到客户端。因此,我假设最快的方法是通过简单的SELECT(或函数的Ref-Cursor)选择数据,并在客户端中构建XML结构。这将是您的选择2。