Top / .NET備忘録 / 10.oo4o / 02.OraDynaset その(1)

OraDynaset を実装する際、簡単なのは、OracleDataAdapter クラスで Fill メソッドを実行して DataTable を作成し、それを OraDynaset インターフェイスで公開することです。

ただし、以下の問題点があります。

(1) CreateDynaset → MoveFirst → MoveNext の動きと違う。全件引っ張ってきてそれから列挙を開始することになるので、大量データだと時間がかかりそう。

(2) ODP1.x 系と ODP2.x 系で、DataTable に格納されるデータ型が違う。(1.x では .NET型、2.x では ODP.NET データ型)

(2) については、ReturnProviderSpecificTypes プロパティを True にすればよいですが、(1) はちょっといただけません。

OracleCommad クラスの ExecuteReader メソッドが返す、OracleDataReader クラスから Dynaset を実装することにしました。

ファイヤーホース的な実装がわからないとのメールを頂いたので、骨子だけ載せておきます。(Dispose 等は省略。)

using Oracle.DataAccess.Client;

public class OraDynaset
{
    private int ReadCount = 0;
    private int _RowPosition = -2;
    private OracleDataReader Reader;

    public OraDynaset(OracleDataReader reader) {
        Reader = reader;
    }

    protected void ReadAll() {
        Read(int.MaxValue);
    }

    protected bool Read(int rowCount) {
        if (Reader != null) {
            while (ReadCount < rowCount) {
                if (Reader.Read()) {
                    ReadCount++;
                    OnRead(Reader);
                } else {
                    Reader.Dispose();
                    Reader = null;
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    protected virtual void OnRead(OracleDataReader reader) {
        // ここで OracleDataReader からデータを取り出し 
        // DataTable に保管する等の処理を行う。
    }

    protected int RowPosition {
        get {
            return _RowPosition;
        }
        set {
            if (value < -1) {
                _RowPosition = -2;
            } else if (value == -1) {
                _RowPosition = -1;
            } else if (value < ReadCount) {
                _RowPosition = value;
            } else {
                if (Read(value + 1)) {
                    _RowPosition = value;
                } else {
                    _RowPosition = ReadCount;
                }
            }
        }
    }

    public void MoveFirst() {
        RowPosition = 0;
    }

    public void MovePrevious() {
        RowPosition--;
    }

    public void MoveNext() {
        RowPosition++;
    }

    public void MoveLast() {
        RowPosition = RecordCount - 1;
    }

    public int RecordCount {
        get {
            ReadAll();
            return ReadCount;
        }
    }

    public bool Bof {
        get {
            if (RowPosition < 0) {
                return true;
            }
            return false;
        }
    }

    public bool Eof {
        get {
            if (RowPosition == -2) {
                return true;
            }
            if (RowPosition < ReadCount) {
                return false;
            }
            return Reader == null;
        }
    }
}



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2019-06-24 (月) 15:38:46 (55d)