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

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

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

Re[6]: DB接続クラスについて


(過去ログ 84 を表示中)

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

■49934 / inTopicNo.1)  DB接続クラスについて
  
□投稿者/ teru (18回)-(2010/05/24(Mon) 15:39:59)

分類:[.NET 全般] 

こんにちは。現在visualC#2008でDB(SQL Server 2008)を使用してアプリを作っています。

今までDBからデータセットにデータを読み込んで処理していたのですが、何度も
接続文字列などをコピペするのが面倒くさく、クラスにまとめてみることにしました。

接続型のクラスサンプルは比較的見るのですが、非接続型のクラスは見たことがありません。
どのように作成すればよいのでしょうか?

namespace ○○
{
class SqlServerDBConnection
{
private DataSet dset = new DataSet();
private SqlConnection cn = new SqlConnection();

SqlDataAdapter dAdp;

cn.ConnectionString = @"Data Source = .\SQLEXPRESS;"
        以下省略

}
}

のように書いていたのですが、無効なトークン '=' が クラス、構造体またはインターフェイスのメンバ宣言で使用されています。というエラーメッセージが出てしまいました。。。orz

皆さんならどのようなクラスを作るのでしょうか?

引用返信 編集キー/
■49937 / inTopicNo.2)  Re[1]: DB接続クラスについて
□投稿者/ はつね (1269回)-(2010/05/24(Mon) 16:48:43)
No49934 (teru さん) に返信
> 接続型のクラスサンプルは比較的見るのですが、非接続型のクラスは見たことがありません。
> どのように作成すればよいのでしょうか?

非接続型だったら簡単に言えば、GetRecordsとSetRecordsみたいな感じで、DataSetにDBから値をとってくるのと
DataSetの値をDBに反映するのがあればいいじゃ?

で、それぞれの中で
Connection接続
CommandにSQL設定
Adapter関係の処理
を行う感じで。


> cn.ConnectionString = @"Data Source = .\SQLEXPRESS;"

分の終わりの ; がないようですけど(文字列の中にはありますが)。

引用返信 編集キー/
■49942 / inTopicNo.3)  Re[1]: DB接続クラスについて
□投稿者/ もりお (223回)-(2010/05/24(Mon) 22:48:51)
No49934 (teru さん) に返信

> どのように作成すればよいのでしょうか?

TableAdapter を作成するという素敵な手段があります。
TableAdapter を使わずにデータアクセスクラスを作成するということであれば
、抽象クラスにテーブル間で共通の処理を記述して、テーブルごとに異なる部分
を派生クラスに記述して、類似のクラスを作成する手間を削減するという、そん
な作戦を私はお勧めします。

protected void Page_Load(object sender, EventArgs e) {
  DataTable table = new DataTable();
  DataAccesserBase accesser = new TestAccesser();
  accesser.Fill(table);
}

abstract public class DataAccesserBase {
  public Int32 Fill(DataTable table) {
    using (DbConnection connection = CreateConnection()) {
      using (DbCommand selectCommand = CreateSelectCommand(connection)) {
        using (DbDataAdapter dataAdapter = CreateDataAdapter(selectCommand)) {
          return dataAdapter.Fill(table);
        }
      }
    }
  }

  protected DbConnection CreateConnection() {
    DbConnection connection = Factory.CreateConnection();
    connection.ConnectionString = ConnectionString;
    return connection;
  }

  protected DbCommand CreateSelectCommand(DbConnection connection) {
    DbCommand command = Factory.CreateCommand();
    command.CommandText = SelectCommandText;
    command.Connection = connection;
    foreach (DbParameter parameter in SelectCommandParameters) {
      command.Parameters.Add(parameter);
    }
    return command;
  }

  protected DbDataAdapter CreateDataAdapter(DbCommand command) {
    DbDataAdapter adapter = Factory.CreateDataAdapter();
    adapter.SelectCommand = command;
    return adapter;
  }

  abstract protected DbProviderFactory Factory {
    get;
  }

  abstract protected string ConnectionString {
    get;
  }

  abstract protected string SelectCommandText {
    get;
  }

  abstract protected DbParameter[] SelectCommandParameters {
    get;
  }
}

public class TestAccesser : DataAccesserBase {
  protected override DbProviderFactory Factory {
    get {
      return SqlClientFactory.Instance;
    }
  }

  protected override string ConnectionString {
    get {
      return @"Data Source=...";
    }
  }

  protected override string SelectCommandText {
    get {
      return "select * from [test]";
    }
  }

  protected override DbParameter[] SelectCommandParameters {
    get {
      return new SqlParameter[] { };
    }
  }
}

引用返信 編集キー/
■49945 / inTopicNo.4)  Re[2]: DB接続クラスについて
□投稿者/ teru (21回)-(2010/05/24(Mon) 23:50:12)
皆さまご返信ありがとうございます。

実はクラスを自作した経験がなく(汗
ちょっと勉強がてらに作ってみようと思ったのがきっかけなんですが、なかなか難しいですね。

もりおさんのクラス拝見しましたが、正直難しいので一度動かしてみて理解したいと思います。
自分もスマートなコードが書けるようになりたいです。

はつねさんのロジック、もりおさんのサンプル提示ありがとうございました。
引用返信 編集キー/
■50058 / inTopicNo.5)  Re[3]: DB接続クラスについて
□投稿者/ teru (22回)-(2010/05/27(Thu) 13:17:55)
お世話になります。

もりおさんのクラスで実行してみたのですが、Sql文を切り替える方法がわかりません。
現在以下のようなSql文を実行しているのですが、たとえば"select * from M_SCORE、select ROUND(AVG([1位率])とSql文を切り替えて実行するにはどうすればよいのでしょうか?

DataSet dset = new DataSet();
SqlDataAdapter dAdp,
dAdpRate1st,
dAdpRate4th,
dAdpMeanRank,
dAdpPointBalance,
dAdpChipBalance,
dAdpTotalBalance,
dAdpLocatPrice,
dAdpAllBalance;

SqlConnection cn = new SqlConnection();
cn.ConnectionString = @"Data Source = 接続文字列

// クエリの総信
dAdp = new SqlDataAdapter("select * from M_SCORE", cn);
dAdpRate1st = new SqlDataAdapter("select ROUND(AVG([1位率]), 3) as トップ率 from M_SCORE", cn);
dAdpRate4th = new SqlDataAdapter("select ROUND(AVG([4位率]), 3) as ラス率 from M_SCORE", cn);
dAdpMeanRank = new SqlDataAdapter("select ROUND(AVG(平均順位), 3) as 平均順位 from M_SCORE", cn);
dAdpPointBalance = new SqlDataAdapter("select sum(ポイント収支) as ポイント収支 from M_SCORE", cn);
dAdpChipBalance = new SqlDataAdapter("select sum(チップ収支) as チップ収支 from M_SCORE", cn);
dAdpTotalBalance = new SqlDataAdapter("select sum(合計収支) as 合計収支 from M_SCORE", cn);
dAdpLocatPrice = new SqlDataAdapter("select sum(場代) as 場代 from M_SCORE", cn);
dAdpAllBalance = new SqlDataAdapter("select sum(総収支) as 総収支 from M_SCORE", cn);

// 各データセットに集計
dAdp.Fill(dset, "M_SCORE");
dAdpRate1st.Fill(dset, "RATE_1ST");
dAdpRate4th.Fill(dset, "RATE_4TH");
dAdpMeanRank.Fill(dset, "MEAN_RANK");
dAdpPointBalance.Fill(dset, "POINT_BALANCE");
dAdpChipBalance.Fill(dset, "CHIP_BALANCE");
dAdpTotalBalance.Fill(dset, "TOTAL_BALANCE");
dAdpLocatPrice.Fill(dset, "LOCAT_PRICE");
dAdpAllBalance.Fill(dset, "ALL_BALANCE");

// 各データセットの集計したテーブルをテキストボックスにバインド
dgv.DataSource = dset.Tables["M_SCORE"];
txtRate1st.DataBindings.Add("Text", dset.Tables["RATE_1ST"], "トップ率");
txtRate4th.DataBindings.Add("Text", dset.Tables["RATE_4TH"], "ラス率");
txtMeanRank.DataBindings.Add("Text", dset.Tables["MEAN_RANK"], "平均順位");
txtPointBalance.DataBindings.Add("Text", dset.Tables["POINT_BALANCE"], "ポイント収支");
txtChipBalance.DataBindings.Add("Text", dset.Tables["CHIP_BALANCE"], "チップ収支");
txtTotalBalance.DataBindings.Add("Text", dset.Tables["TOTAL_BALANCE"], "合計収支");
txtLocatPrice.DataBindings.Add("Text", dset.Tables["LOCAT_PRICE"], "場代");
txtAllBalance.DataBindings.Add("Text", dset.Tables["ALL_BALANCE"], "総収支");
引用返信 編集キー/
■50085 / inTopicNo.6)  Re[4]: DB接続クラスについて
□投稿者/ もりお (227回)-(2010/05/27(Thu) 17:48:08)
2010/05/27(Thu) 17:48:40 編集(投稿者)
No50058 (teru さん) に返信

> たとえば"select * from M_SCORE、select ROUND(AVG([1位率])とSql文を切り
> 替えて実行するにはどうすればよいのでしょうか?

私のコードにおいてということであれば、SQL 文ごとにクラスを作成したり、メ
ソッドを追加したりといった対応が考えられます。
それはさておき、なんだか少し申し訳ないのですが、私のコードは見なかったこ
とにして、型指定されたデータセットとテーブルアダプタを利用してはいかがで
しょうか。
テーブルアダプタを用いると、ウィザード画面においてクエリーを追加すること
でコードは自動的に生成されます。プログラムでは自動的に生成されたメソッド
を呼び出すだけです。
型指定されたデータセットを利用することでテーブル名等のスペルミスもなくな
るので安全安心なコーディングができます。

作成の仕方に関してはこちらのサイトが参考になるかと思います。
第2回 データセットとデータテーブル
http://www.atmarkit.co.jp/fdotnet/vblab/vsdbprog_02/vsdbprog_02_02.html

引用返信 編集キー/
■50089 / inTopicNo.7)  Re[5]: DB接続クラスについて
□投稿者/ teru (23回)-(2010/05/27(Thu) 21:22:56)
No50085 (もりお さん) に返信
> 2010/05/27(Thu) 17:48:40 編集(投稿者)
>
> ■No50058 (teru さん) に返信
>
>>たとえば"select * from M_SCORE、select ROUND(AVG([1位率])とSql文を切り
>>替えて実行するにはどうすればよいのでしょうか?
>
> 私のコードにおいてということであれば、SQL 文ごとにクラスを作成したり、メ
> ソッドを追加したりといった対応が考えられます。
> それはさておき、なんだか少し申し訳ないのですが、私のコードは見なかったこ
> とにして、型指定されたデータセットとテーブルアダプタを利用してはいかがで
> しょうか。
> テーブルアダプタを用いると、ウィザード画面においてクエリーを追加すること
> でコードは自動的に生成されます。プログラムでは自動的に生成されたメソッド
> を呼び出すだけです。
> 型指定されたデータセットを利用することでテーブル名等のスペルミスもなくな
> るので安全安心なコーディングができます。
>
> 作成の仕方に関してはこちらのサイトが参考になるかと思います。
> 第2回 データセットとデータテーブル
> http://www.atmarkit.co.jp/fdotnet/vblab/vsdbprog_02/vsdbprog_02_02.html

もりおさん返信ありがとうございます。
コードが自動生成されると勉強にならない気がしまして^^;
もりおさんのクラスを変更して使えるといいのですが、何せクラスをよくわかってないもので、
派生クラスについて調べてみましたが、ちょっと自分には早かったようで(笑

これなら接続文字列だけを定数として書いておくだけでいいのかなぁと思ってしまいました。
もりおさんのようにスマートなクラスを作れるようになりたいです。
引用返信 編集キー/
■50100 / inTopicNo.8)  Re[6]: DB接続クラスについて
□投稿者/ todo (10回)-(2010/05/28(Fri) 09:24:55)
> コードが自動生成されると勉強にならない気がしまして^^;

いえいえ、非接続型のクラスのサンプルとして、物凄く勉強になります。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -