0

我需要一种方法来优化从 Oracle 数据库中将数百万条记录的数据检索到自定义业务对象列表中。从 Oracle 返回的数据是 XML 格式,我需要一种将其序列化为业务对象列表的方法。

我编写的代码工作正常,但是,在将 XML 加载到内存期间执行需要很长时间,特别是当代码到达该行时:

var xDoc = XDocument.Load(xmlReader);   

代码 :

//Custom Business object  
 public class AccountType
    {
        public int AccountTypeID { get; set; }
        public string AccountCode { get; set; }
        public string BookType { get; set; }
        public int Status { get; set; }
    }

//Code that retrieves data from Oracle DB

  using (OracleConnection objOracleConnection = new OracleConnection(strConnectionString))
            {
                using (OracleCommand orclCmd = objOracleConnection.CreateCommand())
                {
                    try
                    {

                        orclCmd.CommandText = strXMLSQL;
                        orclCmd.BindByName = true;
                        orclCmd.XmlCommandType = OracleXmlCommandType.Query;
                        orclCmd.XmlQueryProperties.RootTag = "AccountData";
                        orclCmd.XmlQueryProperties.RowTag = "ROW";

                        objOracleConnection.Open();
                        XmlReader xmlReader = orclCmd.ExecuteXmlReader();
                        var xDoc = XDocument.Load(xmlReader);                             
                        List<AccountType> accountTypes = (from data in xDoc.Root.Elements("ROW")
                                                              select new AccountType
                                                              {
                                                                  AccountTypeID = data.GetIntXMLElementValue("ACCOUNTTYPEID"),
                                                                  AccountCode = data.GetStringXMLElementValue("ACCOUNTCODE"),
                                                                  BookType = data.GetStringXMLElementValue("BOOKTYPE"),
                                                                  Status = data.GetIntXMLElementValue("STATUS")
                                                              }).ToList();

                    }
                    catch (OracleException oracleEx)
                    {
                        throw oracleEx;
                    }
                    catch (Exception generalEx)
                    {
                        throw generalEx;
                    }
                    finally
                    {
                        objOracleConnection.Close();
                    }
 }

任何帮助将不胜感激。

谢谢!

4

2 回答 2

0

您是否需要同时拥有数百万条记录?

数据是否以 XML 格式存储在数据库中?如果不是,您可以使用ExecutePageReader而不是 ExecuteXmlReader

如果它必须是 XML,那么您可以通过调用 id 在 lastId 加 1 和 lastId 加 pageLength 之间的记录来实现自己的寻呼机

于 2012-09-26T17:10:58.833 回答
0

分页是一种选择。在调用 ToList() 之前还使用 PLINQ 进行线程化,因为那是你受到打击的地方。我还要补充一点,删除 XDocument 加载可能会有所帮助。尝试反序列化 xml。假设您的 XML 看起来像这样

<ROWSET>
    <ROW>
        <AccountData>
            <ACCOUNTTYPEID>1</ACCOUNTTYPEID>
            <ACCOUNTCODE>ABC</ACCOUNTCODE>
            <BOOKTYPE>FOO</BOOKTYPE>
            <STATUS>10</STATUS>
        </AccountData>
    </ROW>
    <ROW>
        <AccountData>
            <ACCOUNTTYPEID>2</ACCOUNTTYPEID>
            <ACCOUNTCODE>XYZ</ACCOUNTCODE>
            <BOOKTYPE>BAR</BOOKTYPE>
            <STATUS>20</STATUS>
        </AccountData>
    </ROW>
</ROWSET>

您可以设置以下合约:

[DataContract(Namespace = "")]
public class AccountData
{
    [DataMember(Name = "ACCOUNTTYPEID")]
    public int Id { get; set; }
}

[DataContract(Name = "ROW", Namespace = "")]
public class Row
{
    [DataMember(Name = "AccountData")]
    public AccountData Data { get; set; }
}

[CollectionDataContract(Name="ROWSET", Namespace = "")]
public class RowSet
    : List<Row>
{
}

并像这样反序列化

var s = new DataContractSerializer(typeof(RowSet));
var o = s.ReadObject(xmlreader) as RowSet;

这避免了 XDocument 加载和 LINQ-XML 开销。

于 2012-09-26T17:50:34.590 回答