- PR -

型付DataSetについて

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-04-05 17:03
型付DataSetについて質問します。

DataBaseの各テーブルと1対1になるクラスがあります。
下記のソースは個々のテーブルが継承しなければならない抽象クラスです。
下記のメソッドのSchemaTableプロパティ、Selectメソッド、Findメソッドは
型付のDataTableを返したいと思うのですが、実装方法がまったくわかりません。

型付DataSetを使用するのは初めてです。
また下記のコードは前プロジェクトで使用していたものですが、
InsertCommand、UpdateCommand、DeleteCommandを書かなければならないのが面倒でした。

コードのだめだし、設計のだめだしも含めアドバイスお願いいたします。


''' <summary>
''' DataBaseの個々のテーブルに対応するクラスの抽象クラスです。
''' </summary>
''' <remarks></remarks>
Public MustInherit Class TableTemplate

#Region "インスタンス変数"

''' <summary>
''' テーブル名
''' </summary>
''' <remarks></remarks>
Protected p_TableName As String

''' <summary>
''' コネクションオブジェクト
''' </summary>
''' <remarks></remarks>
Protected p_Connection As System.Data.Common.DbConnection

''' <summary>
''' トランザクションオブジェクト
''' </summary>
''' <remarks></remarks>
Protected p_Transaction As System.Data.Common.DbTransaction

#End Region

#Region "コンストラクタ"

''' <summary>
''' デフォルトコンストラクタ
''' </summary>
''' <remarks></remarks>
Public Sub New()

End Sub

''' <summary>
''' コンストラクタ
''' </summary>
''' <param name="connection">コネクションオブジェクト</param>
''' <remarks></remarks>
Protected Sub New(ByVal connection As System.Data.Common.DbConnection)
Me.New()
Me.p_Connection = connection
End Sub

''' <summary>
''' コンストラクタ
''' </summary>
''' <param name="connection">コネクションオブジェクト</param>
''' <param name="transaction">トランザクションオブジェクト</param>
''' <remarks></remarks>
Protected Sub New(ByVal connection As System.Data.Common.DbConnection, ByVal transaction As System.Data.Common.DbTransaction)
Me.New(connection)
Me.p_Transaction = transaction
End Sub
#End Region

#Region "Publicプロパティ"

''' <summary>
''' コネクションオブジェクトを設定します。
''' </summary>
''' <value>コネクションオブジェクト</value>
''' <remarks></remarks>
Public WriteOnly Property Connection() As System.Data.Common.DbConnection
Set(ByVal value As System.Data.Common.DbConnection)
Me.p_Connection = value
End Set
End Property

''' <summary>
''' トランザクションオブジェクトを設定します。
''' </summary>
''' <value>トランザクションオブジェクト</value>
''' <remarks></remarks>
Public WriteOnly Property Transaction() As System.Data.Common.DbTransaction
Set(ByVal value As System.Data.Common.DbTransaction)
Me.p_Transaction = value
End Set
End Property

''' <summary>
''' 主キー設定した空のテーブルオブジェクトを取得します。
''' </summary>
''' <returns>テーブルオブジェクト</returns>
''' <remarks></remarks>
Public MustOverride ReadOnly Property SchemaTable() As DataTable

#End Region

#Region "Publicメソッド"

''' <summary>
''' 主キーで検索した結果セットを返します。
''' </summary>
''' <param name="key">主キーの配列</param>
''' <returns>データテーブルオブジェクト</returns>
''' <remarks></remarks>
Public MustOverride Function Find(ByVal key() As Object) As DataTable

''' <summary>
''' 条件で検索した結果セットを返します。
''' </summary>
''' <param name="sExpr">条件</param>
''' <returns>データテーブルオブジェクト</returns>
''' <remarks></remarks>
Public MustOverride Function [Select](ByVal sExpr As String) As DataTable

''' <summary>
''' 更新テーブルを元にDBへ更新します。
''' </summary>
''' <param name="table">更新テーブル</param>
''' <remarks></remarks>
Public Overridable Sub Update(ByVal table As DataTable)
'ファクトリーオブジェクトを作成します。
Dim factory As DbProviderFactory = プロバイダ情報からDbProviderFactoryインスタンスを作成します。

'アダプターオブジェクトを作成します。
Dim adapter As System.Data.Common.DbDataAdapter
adapter = factory.CreateDataAdapter

'更新用コマンドオブジェクトを作成しアダプターオブジェクトに設定します。
adapter.InsertCommand = Me.CreateInsertCommand
adapter.UpdateCommand = Me.CreateUpdateCommand
adapter.DeleteCommand = Me.CreateDeleteCommand

'DataBase更新処理
Try
adapter.Update(table)
Finally
adapter.Dispose()
End Try
End Sub

#End Region

#Region "Protectedメソッド"

''' <summary>
''' SQLの結果をデータテーブルオブジェクトで返します。
''' </summary>
''' <param name="sql">SQL文</param>
''' <returns>データテーブルオブジェクト</returns>
''' <remarks></remarks>
Protected Function CreateDataTable(ByVal sql As String) As DataTable
'ファクトリーオブジェクトを作成します。
Dim factory As New CommonSample.DbAccess.DbCommon.DbProviderFactory

'コマンドオブジェクトを作成します。
Dim command As System.Data.Common.DbCommand
command = Me.p_Connection.CreateCommand
command.CommandText = sql
If Not Me.p_Transaction Is Nothing Then
command.Transaction = Me.p_Transaction
End If

'アダプターオブジェクトを作成します。
Dim adapter As System.Data.Common.DbDataAdapter
adapter = factory.CreateDataAdapter
adapter.SelectCommand = command

'データを取得します。
Dim table As DataTable = Me.SchemaTable
Try
adapter.Fill(table)
Finally
command.Dispose()
adapter.Dispose()
End Try

Return table
End Function

''' <summary>
''' 登録用Commandオブジェクトを作成します。
''' </summary>
''' <returns>登録用Commandオブジェクト</returns>
''' <remarks></remarks>
Protected MustOverride Function CreateInsertCommand() As System.Data.Common.DbCommand

''' <summary>
''' 更新用Commandオブジェクトを作成します。
''' </summary>
''' <returns>更新用Commandオブジェクト</returns>
''' <remarks></remarks>
Protected MustOverride Function CreateUpdateCommand() As System.Data.Common.DbCommand

''' <summary>
''' 削除用Commandオブジェクトを作成します。
''' </summary>
''' <returns>削除用Commandオブジェクト</returns>
''' <remarks></remarks>
Protected MustOverride Function CreateDeleteCommand() As System.Data.Common.DbCommand

#End Region

End Class
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-04-05 17:24
引用:

下記のソースは個々のテーブルが継承しなければならない抽象クラスです。


どうしても継承しなければならない理由があるのでしょうか?

データを検索したり更新したりする機能は、
VS2005ならデータセットデザイナが生成する
〜TableAdapter クラスに含まれていますので、
それを使えばいいと思うのですが。
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-04-05 22:58
型付DataSetのインテリセンス機能は使用したいのですが
どうもウィザードを使用する事が気持ち悪くて仕方ありません。

みなさんは型付DataSetを使用していますか?
また使用している場合は画面ごとに必要な数のDataSetを作成しているのでしょうか?
DataBaseの各テーブルごとに作成しているのでしょうか?

規模やチームの.net習熟度にもよると思いますが
.net習熟度の低いチームでは
小規模では画面ごとにDataSetを作成する事はできますが
中規模以上では画面ごとにDataSetを作成するのでは柔軟な要求に耐えられないのではと
危惧しております。
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-04-06 00:27
好みもありますし、意見の分かれる所だとは思いますが…

私は、型指定されたデータセットは
遊び程度にしか使ったことがありません。
O/R マッピングツールのようなものを使うか、
自分でマッピングを実装する方が
オブジェクト指向的に作りやすいので好きです。

ただし、規模の小さいものであれば、
型指定されたデータセットの方が手軽で便利かも知れませんし、
そこは一長一短だと思います。
メンバーのスキルやシステムの規模等から
総合的に判断して決めるのがよいのではないでしょうか。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2007-04-06 08:58
引用:

未記入さんの書き込み (2007-04-05 22:58) より:

みなさんは型付DataSetを使用していますか?


使ってますよ〜
型付きのDataSet以外は、気持ち悪くて使おうと思いませんw

引用:

未記入さんの書き込み (2007-04-05 22:58) より:

また使用している場合は画面ごとに必要な数のDataSetを作成しているのでしょうか?
DataBaseの各テーブルごとに作成しているのでしょうか?


あくまでも僕の場合ですが、小〜中規模のものなら、ひとつのDataSetにDataTableを放り込んでしまいます。

引用:

未記入さんの書き込み (2007-04-05 22:58) より:

規模やチームの.net習熟度にもよると思いますが
.net習熟度の低いチームでは
小規模では画面ごとにDataSetを作成する事はできますが
中規模以上では画面ごとにDataSetを作成するのでは柔軟な要求に耐えられないのではと
危惧しております。


まずは使ってみるのが良いのではないでしょうか。

「気持ち悪い」「習熟度の低いチームには向かない」と言うのは、主観的なご意見でしかないように思います。
_________________
R・田中一郎 -  R.Tanaka.Ichiro’s Blog
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-04-06 10:17
KIさん
返答ありがとうございます。
個人的にはウィザードを使ったブラックボックス的なものよりコードを書く方が好きです。また柔軟な要求にも耐えられるように思えます。

田中一郎さん
返答ありがとうございます。
ブログ読ませていただきました。
型付データセットについてもぜひ書いていただきたいとリクエストしておきます。
ところで
次期プロジェクトでは型付データセットを使用してみようと色々調べているのですが
画面に型付DataSetを作成する方法はたくさんありました。
型付DataSet内でグリッドに表示するデータを作成しグリッドにバインドして更新。
実際の業務ではもっと複雑で
グリッドに表示する際は、まずストアドを呼びだし、その後DBよりデータを取り出す。
グリッドをクリックした際に表示する詳細データ。
コンボボックスのデータ。
更新する際はあるテーブルを更新後、ストアドを呼び出し、その後また別のテーブルを更新する。
習熟度の低いチーム(VB経験者、NETは初めてなど)の場合
画面に配置された型付DataSetのAdapterでこのような処理を作成するのは難しいのではというのが正直な所です。
まだ調べている途中なのですが
DBの各テーブルに対応する型付DataSetを用意し
画面からはコードにて更新するテーブルに対応する型付DataSetへ変更を加え更新する
という方法を検討しています。
グリッドに表示する際のデータやコンボボックスに設定するデータは
画面と対になるクラスより直接SQLを発行して取得した結果をバインドしようと考えています。
ただこの場合、DBの各テーブルに対してDataTableではなくDataSetというのが気になるところです。
田中一郎さんが
画面数100〜規模で.NETが初めてに近いメンバーと開発することになった場合
どのような切り分けをされるのか、もう少し具体的に教えていただけないでしょうか?
*処理手順(あるテーブルを更新後、ストアドを呼び出し、別のテーブルを更新するなど)は別の担当者が決めるので基本的に変える事ができません。
よろしくお願いいたします。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-04-06 11:06
引用:

未記入さんの書き込み (2007-04-05 22:58) より:

.net習熟度の低いチームでは小規模では画面ごとにDataSetを作成する事はできますが
中規模以上では画面ごとにDataSetを作成するのでは柔軟な要求に耐えられないのではと
危惧しております。


その考え方であれば、小規模でも使わない方がよろしいのではないでしょうか。

私はむしろ逆の考えですね... まあ、工数の都合によるところが多いですが。
小規模 == 工数がない, 中規模以上 == 後々の開発/保守の効率を上げたい

柔軟な要求に耐えられないかどうかは、初期設計次第ではないでしょうか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-04-06 11:31
引用:

じゃんぬねっとさんの書き込み (2007-04-06 11:06) より:
その考え方であれば、小規模でも使わない方がよろしいのではないでしょうか。

私はむしろ逆の考えですね... まあ、工数の都合によるところが多いですが。
小規模 == 工数がない, 中規模以上 == 後々の開発/保守の効率を上げたい

柔軟な要求に耐えられないかどうかは、初期設計次第ではないでしょうか?





じゃんぬさん
いつもお世話になっています。

田中一郎さんにも質問したのですがじゃんぬさんにも同様の質問です。

次期プロジェクトでは型付データセットを使用してみようと色々調べているのですが
画面に型付DataSetを作成する方法はたくさんありました。
型付DataSet内でグリッドに表示するデータを作成しグリッドにバインドして更新。
実際の業務ではもっと複雑で
グリッドに表示する際は、まずストアドを呼びだし、その後DBよりデータを取り出す。
グリッドをクリックした際に表示する詳細データ。
コンボボックスのデータ。
更新する際はあるテーブルを更新後、ストアドを呼び出し、その後また別のテーブルを更新する。
習熟度の低いチーム(VB経験者、NETは初めてなど)の場合
画面に配置された型付DataSetのAdapterでこのような処理を作成するのは難しいのではというのが正直な所です。
まだ調べている途中なのですが
DBの各テーブルに対応する型付DataSetを用意し
画面からはコードにて更新するテーブルに対応する型付DataSetへ変更を加え更新する
という方法を検討しています。
グリッドに表示する際のデータやコンボボックスに設定するデータは
画面と対になるクラスより直接SQLを発行して取得した結果をバインドしようと考えています。
ただこの場合、DBの各テーブルに対してDataTableではなくDataSetというのが気になるところです。
田中一郎さんが
画面数100〜規模で.NETが初めてに近いメンバーと開発することになった場合
どのような切り分けをされるのか、もう少し具体的に教えていただけないでしょうか?
*処理手順(あるテーブルを更新後、ストアドを呼び出し、別のテーブルを更新するなど)は別の担当者が決めるので基本的に変える事ができません。
よろしくお願いいたします。

スキルアップ/キャリアアップ(JOB@IT)