2016年11月17日

データベースから値の取得 環境作成

内容

.NETでのデータベースへのアクセスにはいくつか異なる方法がある。
それらデータを取得する方法を挙げてみる。

概要

データストアとして近年はNoSQLなどが普及し始めているが、まだまだRDBMSが主流。
Oracle,MySQL,DB2,PostgreSQLなどいろいろあるが、ここではマイクロソフト社からリリースされているSQL Serverを使用。

SQL Serverのインストール

現時点での最新版は SQL Server 2016です。
無償版であるExpress版があるのでそれをインストールします。
下記からダウンロードできます。
https://www.microsoft.com/ja-JP/download/details.aspx?id=52679

SQL Server Management Studioのインストール

SQL Server Management Studioはデータベースを操作するためのMS謹製ソフト。
今回はあまり使いませんが、実際の開発では必須のツールです。
ダウンロード
https://msdn.microsoft.com/ja-jp/library/mt238290.aspx
詳しい使い方
https://msdn.microsoft.com/ja-jp/library/ms174173.aspx

サンプルデータ取り込み

最近はデフォルトでサンプルデータが入らないんですね。
アドベンチャーワークスなる架空企業のDBが使われるんですが、うまく入らなかった。
NorthWindは一発で上手く行った。

AdventureWorks
https://www.microsoft.com/en-us/download/details.aspx?id=49502

NorthWind
https://northwinddatabase.codeplex.com/

サーバーエクスプローラーでの表示

VisualStudioを起動しサーバーエキスプローラで表示させると、SQL Server Management Studioで取り込んだNorthWindのテーブル一覧が列挙されています。
テーブルの中身を表示させようとしたら以下の警告が表示されました。
ErrorDialog.png

「互換性のないバージョンのSQL Serverが検出されました」とあります。

警告メッセージの意味はくみ取れませんが、どうやらアドインが必要とのことなのでNuGetします。

NuGetSSDT.png

更新プログラムのところにあったMicrosoft SQL Server Data Tools(SSDT) Updateを適用したら下図のように無事表示されました。

VSServerExplorer.png

環境作成は以上。
posted by RR at 02:14 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする

接続型データアクセス

一番プリミティブなデータアクセスの方法

文字列のSQL文からコマンドを作成し、データリーダーを廻して該当データを取得したりする。

結局ここに戻ってくる気がする。

using System.Collections.Generic;
using System.Data.SqlClient;

namespace ClassLibraryConnection
{
    // 非接続型サンプル
    public class ClassSample
    {
        readonly string ConnectionString = @"Server=localhost\SQLEXPRESS;Database=NORTHWND;Integrated Security=True";
        public IList<object[]> GetEmployeesList()
        {
            var list = new List<object[]>();

            using (var con = new SqlConnection(ConnectionString))
            {
                con.Open();

                using (var cmd = new SqlCommand("SELECT * FROM Employees where City='London'", con))
                {
                    var reader = cmd.ExecuteReader();

                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            var rowdata = new object[reader.FieldCount];

                            reader.GetValues(rowdata);

                            list.Add(rowdata);

                        }
                    }
                }
            }

            return list;

        }
    }
}
posted by RR at 22:07 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする

非接続型データアクセス

文字列のSQL文からアダプターを生成し、これを使ってマップ先のデータセットにカポっとFillする。

System.Data.DataSetExtension.dllへ参照を張れば、Linq To DataSetが使える。

下記サンプルはロンドンの従業員を取得している。
最初のは、SQL文の条件式で絞り込んでる。
2つめは、全件取得後にLinqで絞ってる。

using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace ClassLibraryDisconnect
{
    // 接続型サンプル
    public class ClassSample
    {
        string connectionString = @"Server=localhost\SQLEXPRESS;Database=NORTHWND;Integrated Security=True";
        public DataRowCollection GetEmployeesList()
        {

            var commandText = "SELECT * FROM Employees where City = 'London'";

            var adapter = new SqlDataAdapter(commandText, connectionString);

            DataSet ds = new DataSet();

            adapter.Fill(ds);

            return ds.Tables[0].Rows;
        }

        public List<DataRow> GetEmployeesList2()
        {
            var commandText = "SELECT * FROM Employees";

            var adapter = new SqlDataAdapter(commandText, connectionString);

            DataSet ds = new DataSet();

            adapter.Fill(ds);

            DataTable employees = ds.Tables[0];

            return employees.AsEnumerable().Where(row => row.Field<string>("City") == "London").ToList();
        }
    }
}
posted by RR at 22:18 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする

非接続型データアクセス 型付データセット

予めデータベースにある対象のスキーマ情報からエンティティやアダプターなどを生成しておき、タイプセーフにコーディングできるようにしておく。

一時期は大流行りしたが、諸々の事情により廃れつつある。

新規のプロジェクトならEntity Frameworkを使えばよいのだが、既存資産の流用とか考えるとUI層までビッシリ這い込んでいたりするので、それなりに良く見かける。

NewItemDataSet.png

「新規追加」から「データ」にある「データセット」を選択する。名前もそれらしいのを付けておく。

TyoedDataSet.png

拡張子XSDというデザイナー画面が追加される。ここで操作対象のテーブルとかビューとか関連とかGUIで選択していく。

using System.Collections.Generic;
using System.Linq;

namespace ClassLibraryTyedDataSet
{
    public class ClassSample
    {
        public List<DataSetNorthWind.EmployeesRow> GetEmployeesList()
        {
            var ds = new DataSetNorthWind();

            var adapter = new DataSetNorthWindTableAdapters.EmployeesTableAdapter();

            adapter.Fill(ds.Employees);

           return ds.Employees.AsEnumerable().Where(emp => emp.City.Equals("London")).ToList();

        }
    }
}

非接続型とやってることはほぼ同じだが、データセットやデータアダプタークラスがxsdファイルから自動生成された専用のクラスになっており、Linq To DataSetも型情報を指定することなくフィールドへアクセスする方式となっている。
posted by RR at 22:36 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする

Linq To SQL

Linqの有用性を示すために作られたものの、Entity Frameworkの登場により、Linq To SQLは開発中止で今後はEFを使いましょうって話だったような気がするけど、未だに現役だったりしてます。

NewItemLinqToXML.png

「新しい項目の追加」で「データ」より「LINQ to SQLクラス」を選択すると、拡張子dbmlというデザイナ画面が追加されます。

LinqToXML.png

型付データセットと同様に操作対象のテーブルなどを乗っけてけばよい。

このデザイナ画面分に相当するのがSystem.Data.Linq.DataContextクラスを継承して生成されるコンテクストクラスであり、このコンテクストを操作して値を取ったりする。

using System.Collections.Generic;
using System.Linq;

namespace ClassLibraryLinqToSQL
{
    public class ClassLinqToSQL
    {
        public List<Employees> GetEmployeesList()
        {
            using (var context = new DataClassesNorthWndDataContext())
            {
                return context.Employees.Where(emp => emp.City == "London").ToList();
            }
        }
    }
}
posted by RR at 22:51 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする

Entity Framework

新規開発案件でデータベースアクセスが必要な場合に、最初に候補となるアクセス方式。

最近はこればっかり良く見かけます。

非常に豊富な機能がある分だけ落とし穴もあるような気がします。

「新らしい項目追加」で「データ」から「ADO.NET Entity Data Model」を選択し、適当に名前を付ける。
NewItemEF.png

「モデルのコンテンツ選択」で「データベースから EF Designer」を選択
EFModelSelection.png

EFはデータベースのスキーマ情報からリバースしてCSコードを生成するのと同様に、デザイナ画面の設定情報からデータベースのスキーマを作成させることも可能です。

「データ接続の選択」はそのまま「次へ」
EFDatabaseSelection.png

「バージョンの選択」は新しい方を選択
EFVsersionSelect.png

操作対象のテーブルを選択。ここでは全部選んでみます。
EFSelectTarget.png

これで終了。拡張子edmxというファイルが生成されれば成功。このようなデザイナが表示されます。
VSEF.png

サンプルコードは以下の通り

using System.Collections.Generic;
using System.Linq;

namespace ClassLibraryEF
{
    public class ClassEntityFramework
    {
        public List<Employees> GetEmployeesList()
        {
            using (var context = new NORTHWNDEntities())
            {
               return context.Employees.Where(emp => emp.City == "London").ToList();
            }
        }
    }
}

Linq To SQLとほぼ同等のコードですが、NORTHWNDEntitiesの親クラスはSystem.Data.Entity.DbContextクラスになります。また、リンクで対象を絞っていますが、これはLinq To Entityになります。

Entity Frameworkによりデータアクセスする処理が記述されたライブラリとメインアセンブリ(エントリポイントがあるアセンブリ)とが異なる場合だと、もう少し手間が必要です。

・メインアセンブリのアプリケーション構成ファイルにEF用の設定を転記
 接続文字列などは実装したDLLの構成ファイルに配置されるので、それをコピペする必要あり。
・アセンブリのプレロードが必要
 メインアセンブリ内でDBアクセス処理を行っていなくても、EF系ライブラリへの参照が必要。NuGetしておく。
posted by RR at 23:17 | Comment(0) | DBアクセス | このブログの読者になる | 更新情報をチェックする