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

ページングは​​オプションです。また、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 に答える
0

何百万ものレコードが一度に必要ですか?

データはデータベースに XML として保存されていますか? そうでない場合は、ExecuteXmlReader の代わりに ExexcutePageReader を使用できます

XML でなければならない場合は、id が lastId + 1 と lastId + pageLength の間にあるレコードを呼び出して、独自のページャーを実装できます。

于 2012-09-26T17:10:58.833 に答える