我需要一种方法来优化从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();
}
}
非常感谢任何帮助。
谢谢!
答案 0 :(得分:0)
您是否一次需要数百万条记录?
数据是否以XML格式存储在数据库中?如果不是,您可以使用ExexcutePageReader而不是ExecuteXmlReader
如果必须是XML,则可以通过调用id在lastId加1和lastId加上pageLength
之间的记录来实现自己的寻呼机答案 1 :(得分: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开销。