C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: oo4oからodp.netへの変換


(過去ログ 149 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■86717 / inTopicNo.1)  oo4oからodp.netへの変換
  
□投稿者/ yuuki (1回)-(2018/03/02(Fri) 17:22:06)

分類:[.NET 全般] 

いつも勉強させていただいてます。

VB6⇒VB.NETへのコンバージョンについてご相談させていただきます。

データベースアクセスがoo4oからodp.netへ変換しないといけません。
oo4oのアクセス部分をそれぞれ、odp.netのクラスに機械的に変換すれば全く可能であることはわかっているのですが、もっと楽にする方法はないかと考えています。

そこで、oo4oの定義クラスのメソッド・プロパティをodp.netの同義のメソッド・プロパティに変換するラッピングクラスを作成すれば、oo4oのデータアクセス部分をコーディング変更なしで従来と同じ結果が取得できないかと。

oo4oのクラス:odp.netのクラス
OraSessionClass ⇒ OracleConnection
OraDatabase ⇒ OracleConnection
OraDynaset ⇒ OracleDataReader

1)現行oo4oの参照ライブラリを削除
2)oo4oのクラスでエラーが発生する
3)自作でoo4oのクラスを作成
4)oo4oの各クラスのメソッド、プロパティをope.netの同様の内容に変換するラッピングクラスとする

上記で、理屈上、oo4oのアクセス方法で、実際のDBアクセスはodp.netが行うといったことが可能だと思うのですが、いかがでしょうか。

Namespace OracleInProcServer
    Public Enum dbOption
        ORADB_DEFAULT = &H0&
    End Enum

    Public Enum dynOption
        ORADYN_DEFAULT = &H0&
    End Enum

    'oo4oのOraSessionClassラッピングクラス
    Public Class OraSessionClass
        'ODP.NETのクラス
        Public oraConnection As Oracle.DataAccess.Client.OracleConnection

        Public Function OpenDatabase(ByVal service As String, ByVal userpass As String, ByVal type As dbOption) As OraDatabase
            '・・・・
            '・・・・
            '・・・・
            Return New OraDatabase
        End Function

    End Class

    'oo4oのOraDatabaseラッピングクラス
    Public Class OraDatabase
        'ODP.NETのクラス
        Public oraConnection As Oracle.DataAccess.Client.OracleConnection

        Public Function CreateDynaset(ByVal strSQL As String, ByVal type As dynOption) As OraDynaset
            '・・・・
            '・・・・
            '・・・・

            Return New OraDynaset
        End Function
    End Class

    'oo4oのOraDynasetラッピングクラス
    Public Class OraDynaset
        Public dataReader As Oracle.DataAccess.Client.OracleDataReader
        '・・・・
        '・・・・
        '・・・・
    End Class
End Namespace

方向性は、上記のようにoo4oと全く同じクラスを用意すれば、DBアクセス部分は変更なしで、済むはず・・。
と、思っているのですが、可能でしょうか?

OraSessionClassとOraDatabaseは何となく想像がつくのですが、OraDynasetのFields辺りのデータ取得の部分のイメージがわかないです。
方向性だけでも結構ですのでご教授しただけたらと思います。

※一部VB6独自の特殊なデータの取得(OraDynaset.Fields!Doc_1)などは、さすがに手作業で変換しないといけないと思ってます。




引用返信 編集キー/
■86718 / inTopicNo.2)  Re[1]: oo4oからodp.netへの変換
□投稿者/ sima (3回)-(2018/03/02(Fri) 19:30:17)
No86717 (yuuki さん) に返信
> いつも勉強させていただいてます。
>
> VB6⇒VB.NETへのコンバージョンについてご相談させていただきます。
>
> データベースアクセスがoo4oからodp.netへ変換しないといけません。
> oo4oのアクセス部分をそれぞれ、odp.netのクラスに機械的に変換すれば全く可能であることはわかっているのですが、もっと楽にする方法はないかと考えています。
>
> そこで、oo4oの定義クラスのメソッド・プロパティをodp.netの同義のメソッド・プロパティに変換するラッピングクラスを作成すれば、oo4oのデータアクセス部分をコーディング
> 変更なしで従来と同じ結果が取得できないかと。

それ以前に、
1)現在使用している oracle のバージョンは何でしょうか?
2)DotNet フレームワークのバージョンは何を使うつもりでしょうか?
3)Visual Studio のバージョンは何にするつもりでしょうか?
4)odp.net のバージョンはどれにするつもりでしょうか?

oracle が 9i 以前だとしたらあまり新しいコネクター(ODBC, odp.net)は使い辛いのですが、古いコネクターを探す方が面倒でしょう

他に、oo4o の時代には当たり前のやり方が今は別のやり方の方が良い事があるかもしれません。
こういったことは単純なクラスの置換えでは対処しづらいと考えます。
又、 dotNet では ストアードプロシジャーやビューやクエリーの実行で引数が使えるのでクエリー文字列を連結して
組み立てなくて済む場合がありますが、これも単純なクラスの置換えでは実現しやすそうには思えません。

dotNet ではデーターベースを扱う時はデーターセットやデーターテーブルなどを使うのが標準なので oo4o に準拠したクラス構成では
dotNet の利点が生かせないような気がします。
引用返信 編集キー/
■86720 / inTopicNo.3)  Re[1]: oo4oからodp.netへの変換
□投稿者/ 魔界の仮面弁士 (1584回)-(2018/03/02(Fri) 22:34:30)
2018/03/02(Fri) 22:41:49 編集(投稿者)

No86717 (yuuki さん) に返信
> VB6⇒VB.NETへのコンバージョンについてご相談させていただきます。

WinForm への画面表示や編集(DataGridView等)を伴うなら、
 1: System.Data.OracleClient 名前空間
 2: Oracle.DataAccess 名前空間
 3: Oracle.ManagedDataAccess 名前空間
のいずれかを用いて、DataSet を通じて編集・更新することが多いです。
(3 を推奨 / 1 は非推奨)


一方、集計処理やバッチ処理といったものであれば、DataSet はあまり使われず、
DataReader と Command を使う機会が増えます。


> データベースアクセスがoo4oからodp.netへ変換しないといけません。
ODP.NET / ADO.NET は、『非接続型』というアプローチを取っています。下記参照。
http://otndnld.oracle.co.jp/easy/dotnet/oo4otoodp/

その意味において、ODP.NET(あるいは ADO.NET)の設計思想に近いのは
oo4o よりもむしろ ADODB の方です。

DataSet / DataTable および DataAdapter を通じた取得と更新という考え方は、
ADODB の「オフライン Recordset」「リシェイプ」「バッチ更新モード」に
近いところがあるのですが、oo4o には該当する機能が無かったはず…。


> odp.netのクラスに機械的に変換すれば全く可能であることはわかっているのですが、
ODP.NET には、OO4O の「編集可能な OraDynaset」に該当する物がありません。

ODP.NET/ADO.NET で DataSet を通じてバッチ更新する処理は、
オプティミスティックな更新となります。


> OraDynaset ⇒ OracleDataReader
「DataReader」の文字通り、これは ORADYN_READONLY かつ ORADYN_NOCACHE な OraDynaset に相当するものです。
OracleDataReader を通じて AddNew/Edit/Update することはできないのでご注意ください。


> ラッピングクラスを作成すれば、
個人的には、ラッピングはあまりお奨めしていません。

RDO / DAO / ADODB / OO4O の場合は、アーキテクチャが似ているので
相互にラッピングしやすいですが、 ODP.NET / ADO.NET のアーキテクチャは
OO4O のものとは考え方が異なるので、差異を把握した上で実装しないと
VB6 時代の作られ方に引きずられることになってしまい、
ODP.NET / ADO.NET らしい書き方を阻害してしまう危険性があるためです。

たとえば、DataAdapter や TableAdapter は、ODP.NET / ADO.NET で良く使われるものであり、
VB6 で言う所の DataEnvironment に相当する機能と言えるのですが、
oo4o にはこれに相当する機能が無いため、もしもラッピングするのであれば、
本来の機能を阻害することがないようなクラス設計を施さねばなりません。


それゆえ個人的には、ラッピングして処理を内包してしまうのではなく、
基本的には ODP.NET をそのまま用い、それを手助けするためのヘルパーを用意したり、
拡張メソッドで互換機能を構築することをお奨めしておきます。


なお、拡張メソッドで ADO.NET / ODP.NET を機能拡張するという手法は、
System.Data.Linq 名前空間や Dapper 名前空間などで採用されています。


> OraSessionClass ⇒ OracleConnection
> OraDatabase ⇒ OracleConnection
ODP.NET はコネクションプーリングが既定で有効になっているので、
この部分はまとめてしまっても問題は無さそうです。

ただ、OraSessionClass での BeginTrans と
OraDatabase での BeginTrans を区別している場合には
トランザクションの管理単位を見直す必要があるかもしれません。


> OraSessionClassとOraDatabaseは何となく想像がつくのですが、OraDynasetのFields辺りのデータ取得の部分のイメージがわかないです。
OracleDataReader からだと、Item プロパティ や Get型名 メソッドあたり。

DataSet / DataTable からだと、DataRow クラス の
ItemArray プロパティ / Item プロパティ、Field(Of ) 拡張メソッド / SetField(Of ) 拡張メソッド。
DataViewRow の場合は、そのままインデクサでアクセスすれば OK。

データではなく列情報のことだとしたら DataTable の Columns プロパティが相当しますが、
これは Oracle 側の型情報ではなく.NET 側に取り込んだ後の情報となります。
サーバー側のスキーマを得たい場合は OracleDataReader の GetSchemaTable メソッドか
OracleConnection の GetSchema メソッドで得ることができます。
引用返信 編集キー/
■86727 / inTopicNo.4)  Re[2]: oo4oからodp.netへの変換
□投稿者/ yuuki (2回)-(2018/03/05(Mon) 13:31:47)
No86718 (sima さん) に返信
sima 様
ご返答ありがとうございます。

■旧環境
【サーバ】Windows Server 2008(32bit)
 Oracle Database 11g Release 2 (Server)
【クライアント】Windows 7 SP1
 VB6
 oo4o

■新環境
【サーバ】Windows Server 2012 R2 (64bit)
 Oracle Database 12c Release 1 (Server)
【クライアント】Windows 7 SP1 / Windows 10 混在
 vb.net 2013 実行モジュール
 .NET Framework 4.7 を想定
 odp.net 12c Release 4 を想定

※クライアントが32/64bitが混在するかは未確認

>他に、oo4o の時代には当たり前のやり方が今は別のやり方の方が良い事があるかもしれません。
>こういったことは単純なクラスの置換えでは対処しづらいと考えます。
>又、 dotNet では ストアードプロシジャーやビューやクエリーの実行で引数が使えるのでクエリー文字列を連結して
>組み立てなくて済む場合がありますが、これも単純なクラスの置換えでは実現しやすそうには思えません。

>dotNet ではデーターベースを扱う時はデーターセットやデーターテーブルなどを使うのが標準なので oo4o に準拠したクラス構成では
>dotNet の利点が生かせないような気がします。

ご意見ありがとうございます。
もちろん、単純なクラスの置き換えは考えておりません。
oo4oに準拠したクラス構成を作るのではなくて、odp.netのクラスをあたかもoo4oのクラスとして扱えるようなラッピングクラスを考えております。
要はoo4oで使用されているクラス、メソッドを独自クラスで定義し、そのクラスの中でodp.netを利用するという方針を考えています。
もちろん、o4とodp.netでの根本的なデータベースアクセスの違い(非接続型でのデータベースへの自動接続/自動切断)などは独自クラスで吸収するような作りになると思ってます。

そこまで苦労してラッピングクラスを作るのと、DBアクセスしている箇所を全てodp.net用に組み替えるのと、どちらが楽なのか少し疑問になるところがありますが。。
貴重な意見ありがとうございます。
また、何かお気づきの点があればご教授ください。

引用返信 編集キー/
■86728 / inTopicNo.5)  Re[2]: oo4oからodp.netへの変換
□投稿者/ yuuki (3回)-(2018/03/05(Mon) 14:07:17)
No86720 (魔界の仮面弁士 さん) に返信
魔界の仮面弁士 様

ご返答ありがとうございます。
非常に貴重な意見を頂いたと思っております。
(ちなみに以前にも魔界の仮面弁士様にはご助力いただいた者です)

拡張メソッドですか。なるほど、そこの発想は少しありませんでした。

そもそも、今回ラッピングクラスを考えたのは、
現状200機能ほどある、oo4oを使用した機能はDBアクセスは至極単純なものになっており、
そのほとんどが
■データ取得
OraDatabase.CreateDynaset(sql_str, ORADYN_READONLY)
⇒.Fields(1).Valueで値参照
■データ更新系
stringにDMLを作成
⇒OraDatabase.ExecuteSQLで実行
といった形で形成されています。

その一つ一つをodp.net用に作り替えるより、ラッピングクラス作ったほうが、ソース自体はほぼ変更しなくて楽じゃないかな。。と思った次第であります。

質問の記載から、色々ネットで調べてみたところ、やっぱり同じような考えをしている方がいらっしゃいました。
https://takanosho.wordpress.com/2015/12/22/vb-advent-2015/
http://kozhouse.homeip.net/dotnet/oo4o/

機能限定すれば、なんとなくラッピングしたほうが楽な気がしました。
ご指摘のADO.NETの件についても視野にいれて考えてみたいと思います。
ただ、ADO.NETはデータソースへの接続にブリッジが入るのが少し気になるところ。。

>OracleDataReader からだと、Item プロパティ や Get型名 メソッドあたり。

>DataSet / DataTable からだと、DataRow クラス の
>ItemArray プロパティ / Item プロパティ、Field(Of ) 拡張メソッド / SetField(Of ) 拡張メソッド。
>DataViewRow の場合は、そのままインデクサでアクセスすれば OK。

なるほど、なんとなく理解できました。
個人的にどこまでやれるかちょっと挑戦してみたくなりました。
貴重な情報、ありがとうございました。
また、何かお気づきの点があればご教授ください。

よろしくおねがいいたします。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -