none
DataContextのSelect結果のインスタンス化のタイミング及び使用方法について RRS feed

  • 質問

  • System.Data.LinqのDataContextについてです。 環境としては、WindowsForms、.NetFramework4.5、SQLServer2014を前提にしています。 WindowsFormでSQLServerよりデータ取得するロジックで、DBアクセスロジックが散在するのを回避するために、DBアクセス用のクラスを設けました(DBクラスとします)。 その過程で、下記の現象を見つけ、疑問に思いましたので投稿させて頂きます。 (DBクラス)db.Open() ↓ (DBクラス)データ取得 ↓ (DBクラス)db.Close() ↓ (呼出元)取得したデータをToArray() とすると、呼出元でデータが取得できてしまうのですが、呼出元でしかインスタンス化していないはずで、その前にdb.Close()しているのにデータが取得できるのは何故でしょうか。どこかでインスタンス化がされているのでしょうか。 【サンプルコード】 IEnumerable<SampleMaster> hoge () {   try   {     var db = new DataContext();    db.Open();   var data = db.DbContext.SampleMaster    .Where(m => m.testCol == "test");   }   finally   {     db.Close();   } } そもそも、各フォームの中にDBの取得ロジックが散在することを回避したいのですが、この考え方自体は一般的にはどうなのでしょうか。ユーザの入力を受けて、それを条件にしてデータを取得することが基本ですが、外部クラスにすると詳細な条件指定がしづらく、かといって呼出元で条件指定をするとインスタンス化したSelect結果を返り値にしてやり、呼出元でさらにインスタンス化する処理が必要になると思います。となっては最初に戻って各フォームにDBのロジックを書くべきでしょうか。 【サンプルコード】 class DBClass {   SampleMaster[] hoge () {    using (var db = new DataContext()) {      db.Open();         var data = db.DbContext.SampleMaster      .Where(m => m.testCol == "test")       .ToArray();    }   } } 呼出元 var db = new DBClass(); var data = db.hoge().Where(h => h.testCol2 == "testCol2")            .ToArray();
    2018年5月17日 11:12

すべての返信

  • マルチポストのようなので他のポスト先の URL を書いておきます。

    http://bbs.wankuma.com/

    質問者さん>

    マルチポストの意味が分からなければ、それをキーワードにググってヒットする記事を 2, 3 読んでください。決して歓迎されないことが分かるはず。また、このフォーラムでは遠慮いただくようにと管理者の方からお願いが出ています。


    • 編集済み SurferOnWww 2018年5月17日 11:47 誤字訂正
    2018年5月17日 11:46
  • >(呼出元)取得したデータをToArray() とすると、呼出元でデータが取得できてしまうのですが、呼出元でしかインスタンス化していないはずで、その前にdb.Close()しているのにデータが取得できるのは何故でしょうか。

    hogeメソッド内でデータベースから取得し、それをSampleMaster[] に入れているかです。そのデータベースをクローズしたとしてもデータはSampleMaster[] に残っています。それを呼出元で扱うことになるので、結果的に呼出元でToArray()してデータを得ることができます。

    >もそも、各フォームの中にDBの取得ロジックが散在することを回避したいのですが、この考え方自体は一般的にはどうなのでしょうか。

    一般的におかしくはありません。DataContextを直接扱うのではなく、一般的に用いられるTableAdapterを用いると自ずとそのような実装になります。同じようにDataContextでアクセスするロジックを別にまとめて持てば、TableAdapterと同じような持ち方になると思います。

    >ユーザの入力を受けて、それを条件にしてデータを取得することが基本ですが、外部クラスにすると詳細な条件指定がしづらく、

    外部クラスにした場合に条件指定がしづらいというのは、メソッドの引数として渡さなければならないからでしょうか? であれば、これはしづらいに入らないと個人的には思います。

    かといって呼出元で条件指定をするとインスタンス化したSelect結果を返り値にしてやり、呼出元でさらにインスタンス化する処理が必要になると思います。

    これは当たり前のように行うことです。ただ、これを如何に間違いなく楽にわかりやすく実装するかです。
    世の中にはいろいろなデザインパターンがありますが、これらのデザインパターンを実装するには多くの場合、直接ロジックを書くよりも面倒になります。それでもわかりやすいとか、バグが発生しにくくなるとか、いろいろなメリットがあるために使われます。コードをたくさん書かなければならないことが、必ずしも悪ではありません。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    2018年5月18日 1:58
    モデレータ