目次

概要

プログラミング言語に C# もしくは VB.NET を利用してデータベースにアクセスするには、Soma.Core.Dbクラス、もしくは Soma.Core.LocalDbクラスを使用します。
プログラミング言語に F# を利用する場合は DbモジュールとLocalDbモジュール を参照してください。

Soma.Core.Dbクラス と Soma.Core.LocalDbクラス の違いは、コネクションの扱い方にあります。Soma.Core.Dbクラス は、コネクションの生成と破棄を自動で行います。したがって、このクラスのクライアントはコネクションを管理する必要がありません。一方、Soma.Core.LocalDbクラス は、コネクションの生成と破棄を自動で行いません。したがって、このクラスのクライアントはコネクションを管理しなければいけません。

どちらのクラスを使ってもトランザクションは System.Transactions.TransactionScope を用いて制御できます。しかし、ADO.NETデータプロバイダによってはひとつのトランザクションに複数のコネクションを関連付けられません。その場合には、ひとつのトランザクションではひとつのコネクションのみを使用するようにアプリケーションで調整が必要です。Soma.Core.LocalDbクラスは、そのような制限をもつADO.NETデータプロバイダを利用する場合に使用できます。

ひとつのトランザクションに複数のコネクションを関連付けられないという制限は、Microsoft SQL Server Compact 4.0 と SQLite 3 のデータプロバイダにあります。したがって、これらを利用する場合に Soma.Core.LocalDbクラス を使用してください。

このページで示すサンプルコードはすべてC#で記述されています。また、サンプルコード中のローカル変数 db はすべて Soma.Core.Dbクラスのインスタンスを表すものとします。
Query や Execute といったメソッドではSQLを利用可能ですが、SQLの記述の仕方については SQL記述 式言語 を参照してください。

なお、Soma.Core.Dbクラス と Soma.Core.LocalDbクラス の API は、コネクションをパラメータで渡すかどうかを除けば非常に似ています。したがって、このドキュメントでは Soma.Core.Dbクラス を中心に説明します。

Soma.Core.Db

Soma.Core.Dbクラスのシグネチャは以下の通りです。

シグネチャ
public class Db : IDb
{
    // Constructors
    public Db(IDbConfig config);

    // Methods
    public override void Call<T>(T procedure) where T: class;
    public override void Delete<T>(T entity) where T: class;
    public override void Delete<T>(T entity, DeleteOpt opt) where T: class;
    public override int Execute(string sql);
    public override int Execute(string sql, object condition);
    public override T ExecuteReader<T>(Func<DbDataReader, T> handler, string  sql);
    public override T ExecuteReader<T>(Func<DbDataReader, T> handler, string  sql, object condition);
    public override T Find<T>(object id) where T: class, new();
    public override T FindWithVersion<T>(object id, object version) where T: class, new();
    public override void Insert<T>(T entity) where T: class;
    public override void Insert<T>(T entity, InsertOpt opt) where T: class;
    public override IList<T> Paginate<T>(string sql, long offset, long limit);
    public override IList<T> Paginate<T>(string sql, long offset, long limit, object condition);
    public override Tuple<IList<T>, long> PaginateAndCount<T>(string sql, long offset, long limit);
    public override Tuple<IList<T>, long> PaginateAndCount<T>(string sql, long offset, long limit, object condition);
    public override IEnumerable<T> PaginateOnDemand<T>(string sql, long offset, long limit);
    public override IEnumerable<T> PaginateOnDemand<T>(string sql, long offset, long limit, object condition);
    public override IList<T> Query<T>(string sql);
    public override IList<T> Query<T>(string sql, object condition);
    public override IEnumerable<T> QueryOnDemand<T>(string sql);
    public override IEnumerable<T> QueryOnDemand<T>(string sql, object condition);
    public override T TryFind<T>(object id) where T: class, new();
    public override T TryFindWithVersion<T>(object id, object version) where T: class, new();
    public override void Update<T>(T entity) where T: class;
    public override void Update<T>(T entity, UpdateOpt opt) where T: class;

    // Properties
    public override IDbConfig DbConfig { get; }
}

これらの各メソッドについては、このページでそれぞれ詳細を説明します。

Soma.Core.Dbクラスの典型的な使い方を以下に示します。

典型的な利用例
var db = new Db(new Config());

using (var tx = new TransactionScope())
{
    var emp = db.Find<Employee>(1);
    emp.EmployeeName = "Hoge";
    db.Update(emp);
    db.Delete(emp);

    tx.Complete();
}

この例のポイントを説明します。
  • Soma.Core.Dbのインスタンスは設定を指定して生成します。
  • Soma.Core.Dbのインスタンスはスレッドセーフです。複数のスレッドで同時に使用できます。
  • トランザクションは System.Transactions.TransactionScopeクラスを用いて制御します。

Soma.Core.LocalDb

Soma.Core.LocalDbクラスのシグネチャは以下の通りです。

シグネチャ
public class LocalDb : ILocalDb
{
    // Constructors
    public LocalDb(IDbConfig config);

    // Methods
    public override void Call<T>(DbConnection connection, T procedure) where T: class;
    public override DbConnection CreateConnection();
    public override void Delete<T>(DbConnection connection, T entity) where T: class;
    public override void Delete<T>(DbConnection connection, T entity, DeleteOpt opt) where T: class;
    public override int Execute(DbConnection connection, string sql);
    public override int Execute(DbConnection connection, string sql, object condition);
    public override T ExecuteReader<T>(DbConnection connection, Func<DbDataReader, T> handler, string  sql);
    public override T ExecuteReader<T>(DbConnection connection, Func<DbDataReader, T> handler, string  sql, object condition);
    public override T Find<T>(DbConnection connection, object id) where T: class, new();
    public override T FindWithVersion<T>(DbConnection connection, object id, object version) where T: class, new();
    public override void Insert<T>(DbConnection connection, T entity) where T: class;
    public override void Insert<T>(DbConnection connection, T entity, InsertOpt opt) where T: class;
    public override IList<T> Paginate<T>(DbConnection connection, string sql, long offset, long limit);
    public override IList<T> Paginate<T>(DbConnection connection, string sql, long offset, long limit, object condition);
    public override Tuple<IList<T>, long> PaginateAndCount<T>(DbConnection connection, string sql, long offset, long limit);
    public override Tuple<IList<T>, long> PaginateAndCount<T>(DbConnection connection, string sql, long offset, long limit, object condition);
    public override IEnumerable<T> PaginateOnDemand<T>(DbConnection connection, string sql, long offset, long limit);
    public override IEnumerable<T> PaginateOnDemand<T>(DbConnection connection, string sql, long offset, long limit, object condition);
    public override IList<T> Query<T>(DbConnection connection, string sql);
    public override IList<T> Query<T>(DbConnection connection, string sql, object condition);
    public override IEnumerable<T> QueryOnDemand<T>(DbConnection connection, string sql);
    public override IEnumerable<T> QueryOnDemand<T>(DbConnection connection, string sql, object condition);
    public override T TryFind<T>(DbConnection connection, object id) where T: class, new();
    public override T TryFindWithVersion<T>(DbConnection connection, object id, object version) where T: class, new();
    public override void Update<T>(DbConnection connection, T entity) where T: class;
    public override void Update<T>(DbConnection connection, T entity, UpdateOpt opt) where T: class;

    // Properties
    public override IDbConfig DbConfig { get; }
}

Soma.Core.LocalDbクラスは、Soma.Core.Dbクラスと比較して次の点が異なっています。
  • CreateConnectionメソッドを持ちます。
  • CreateConnectionメソッド以外のすべてのメソッドの第一パラメータは System.Data.Common.DbConnection です。

これらの点を除けば、各メソッドの仕様はSoma.Core.Dbクラスの同名のメソッドと同等です。したがって、各メソッドの仕様はSoma.Core.Dbクラスの同名のメソッドの説明を参照してください。

Soma.Core.LocalDbクラスの典型的な使い方を以下に示します。

典型的な利用例
var db = new LocalDb(new Config());

using (var tx = new TransactionScope())
using (var con = db.CreateConnection())
{
    var emp = db.Find<Employee>(con, 1);
    emp.EmployeeName = "Hoge";
    db.Update(con, emp);
    db.Delete(con, emp);

    tx.Complete();
}

この例のポイントを説明します。
  • Soma.Core.LocalDbのインスタンスは設定を指定して生成します。
  • Soma.Core.LocalDbのインスタンスはスレッドセーフです。複数のスレッドで同時に使用できます。
  • トランザクションは System.Transactions.TransactionScopeクラスを用いて制御します。
  • コネクションは Soma.Core.LocalDb の CreateConnectionメソッドにより生成します。
  • 取得したコネクションは、Soma.Core.LocalDbの他のメソッドの呼び出しに使用します。
  • ひとつのトランザクションにはひとつのコネクションのみを関連付けるようにします。

Dbコンストラクタ

コンストラクタはSoma.Core.IDbConfig型の引数を取ります。
以下にコンストラクタを呼び出す例を示します。

例 : コンストラクタの呼び出し
internal class MyConfig : MsSqlConfig
{
    public override string ConnectionString { get { return "Data Source=.;Initial Catalog=Soma.Tutorial;Integrated Security=True"; } }
}

internal class Program
{
    private static void Main()
    {
        var db = new Db(new MyConfig());
        ...
    }
}

DbConfigプロパティ

コンストラクタで渡したIDbConfig型のインスタンスはDbConfigプロパティにより取得できます。

例 : IDbConfigの取得
var dbConfig = db.DbConfig;

Queryメソッド

SELECTのSQLを指定して複数件をILlist<T>で取得します。
Queryメソッドのジェネリックパラメータには基本型、クラス型、タプル型、dynamic型のいずれかを指定できます。ここに指定された型が戻り値のIListの要素の型になります。
タプル型の要素は基本型もしくはクラス型でなければいけません。タプル型の要素に基本型とクラス型が混在する場合は、基本型がクラス型より前に宣言されなければいけません。
第一引数はSQL、第二引数は問い合わせ条件に利用する匿名型のインスタンスです。

さまざまなジェネリックパラメータを用いた例を以下に示します。

例 : ジェネリックパラメータが基本型
var empList = 
  db.Query<string>(
    "select EmployeeName from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがクラス型
var empList = 
  db.Query<Employee>(
    "select * from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型
var empList = 
  db.Query<Tuple<string, decimal>>(
    "select EmployeeName, Salary from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素がクラス型
var deptEmpList = 
  db.Query<Tuple<Department, Employee>>(
    "select d.*, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型とクラス型の混在
var empList = 
  db.Query<Tuple<string, Employee>>(
    "select d.DepartmentName, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがdynamic型
var empList = 
  db.Query<dynamic>(
    "select EmployeeId, EmployeeName from Employee where Salary > /* salary */0",
    new { salary = 1000M} );
foreach (emp in empList) {
  Console.WriteLine("{0}, {1}", emp.EmployeeId, emp.EmployeeName);
}

QueryOnDemandメソッド

SELECTのSQLを指定して複数件をIEnumerable<T>で取得します。SQLは、戻り値のシーケンスが評価されるまでは実行されません。
QueryOnDemandメソッドのジェネリックパラメータには基本型、クラス型、タプル型、dynamic型のいずれかを指定できます。ここに指定された型が戻り値のIEnumerableの要素の型になります。
タプル型の要素は基本型もしくはクラス型でなければいけません。タプル型の要素に基本型とクラス型が混在する場合は、基本型がクラス型より前に宣言されなければいけません。
第一引数はSQL、第二引数は問い合わせ条件に利用する匿名型のインスタンスです。

さまざまなジェネリックパラメータを用いた例を以下に示します。

例 : ジェネリックパラメータが基本型
var empSeq = 
  db.QueryOnDemand<string>(
    "select EmployeeName from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがクラス型
var empSeq = 
  db.QueryOnDemand<Employee>(
    "select * from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型
var empSeq = 
  db.QueryOnDemand<Tuple<string, decimal>>(
    "select EmployeeName, Salary from Employee where Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素がクラス型
var deptEmpSeq = 
  db.QueryOnDemand<Tuple<Department, Employee>>(
    "select d.*, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型とクラス型の混在
var empSeq = 
  db.QueryOnDemand<Tuple<string, Employee>>(
    "select d.DepartmentName, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0",
    new { salary = 1000M} );

例 : ジェネリックパラメータがdynamic型
var empSeq = 
  db.QueryOnDemand<dynamic>(
    "select EmployeeId, EmployeeName from Employee where Salary > /* salary */0",
    new { salary = 1000M} );
foreach (emp in empSeq) {
  Console.WriteLine("{0}, {1}", emp.EmployeeId, emp.EmployeeName);
}

Pagenateメソッド

SELECTのSQLを指定して複数件をIList<T>で取得します。指定したSQLはページング用のSQLに変換されて実行されます。使用するDBの設定によっては元のSQLに order by 句が指定されている必要があります。
Pagenateメソッドのジェネリックパラメータには基本型、クラス型、タプル型、dynamic型のいずれかを指定できます。ここに指定された型が戻り値のlistの要素の型になります。
タプル型の要素は基本型もしくはクラス型でなければいけません。タプル型の要素に基本型とクラス型が混在する場合は、基本型がクラス型より前に宣言されなければいけません。
第一引数はSQL、第二引数はoffset、第三引数はlimit、第四引数はは問い合わせ条件に利用する匿名型のインスタンスです。

SQLの変換例を示します。

C# code
var empList = 
  db.Pagenate<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );
変換され実行されるSQL
select 
  * 
from 
  ( select 
      temp_.*, 
      row_number() over( order by Salary) as soma_rownumber_ 
    from 
      ( select EmployeeName from Employee where Salary > @p0 ) as temp_ 
  ) as temp2_ 
where 
  soma_rownumber_ > @p1
  and 
  soma_rownumber_ <= @p2
パラメータ@p0、@p1、@p2 にはそれぞれ 1000M、10、60 がバインドされます。

さまざまなジェネリックパラメータを用いた例を以下に示します。

例 : ジェネリックパラメータが基本型
var empList = 
  db.Pagenate<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがクラス型
var empList = 
  db.Pagenate<Employee>(
    "select * from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型
var empList = 
  db.Pagenate<Tuple<string, decimal>>(
    "select EmployeeName, Salary from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素がクラス型
var deptEmpList = 
  db.Pagenate<Tuple<Department, Employee>>(
    "select d.*, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by e.Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型とクラス型の混在
var empList = 
  db.Pagenate<Tuple<string, Employee>>(
    "select d.DepartmentName, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by e.Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがdynamic型
var empList = 
  db.Pagenate<dynamic>(
    "select EmployeeId, EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );
foreach (emp in empList ) {
  Console.WriteLine("{0}, {1}", emp.EmployeeId, emp.EmployeeName);
}

PagenateOnDemandメソッド

SELECTのSQLを指定して複数件をIEnumerable<T>で取得します。SQLは、戻り値のシーケンスが評価されるまでは実行されません。指定したSQLはページング用のSQLに変換されて実行されます。使用するDBの設定によっては元のSQLに order by 句が指定されている必要があります。
PagenateOnDemandメソッドのジェネリックパラメータには基本型、クラス型、タプル型、dynamic型のいずれかを指定できます。ここに指定された型が戻り値のIEnumerableの要素の型になります。
タプル型の要素は基本型もしくはクラス型でなければいけません。タプル型の要素に基本型とクラス型が混在する場合は、基本型がクラス型より前に宣言されなければいけません。
第一引数はSQL、第二引数はoffset、第三引数はlimit、第四引数はは問い合わせ条件に利用する匿名型のインスタンスです。

SQLの変換例を示します。

C# code
var empSeq = 
  db.PagenateOnDemand<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );
変換され実行されるSQL
select 
  * 
from 
  ( select 
      temp_.*, 
      row_number() over( order by Salary) as soma_rownumber_ 
    from 
      ( select EmployeeName from Employee where Salary > @p0 ) as temp_ 
  ) as temp2_ 
where 
  soma_rownumber_ > @p1
  and 
  soma_rownumber_ <= @p2
パラメータ@p0、@p1、@p2 にはそれぞれ 1000M、10、60 がバインドされます。

さまざまなジェネリックパラメータを用いた例を以下に示します。

例 : ジェネリックパラメータが基本型
var empSeq = 
  db.PagenateOnDemand<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがクラス型
var empSeq = 
  db.PagenateOnDemand<Employee>(
    "select * from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型
var empSeq = 
  db.PagenateOnDemand<Tuple<string, decimal>>(
    "select EmployeeName, Salary from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素がクラス型
var deptEmpSeq = 
  db.PagenateOnDemand<Tuple<Department, Employee>>(
    "select d.*, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型とクラス型の混在
var empSeq = 
  db.PagenateOnDemand<Tuple<string, Employee>>(
    "select d.DepartmentName, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by Salary"
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがdynamic型
var empSeq = 
  db.PagenateOnDemand<dynamic>(
    "select EmployeeId, EmployeeName from Employee where Salary > /* salary */0",
    10,
    50,
    new { salary = 1000M} );
foreach (emp in empSeq) {
  Console.WriteLine("{0}, {1}", emp.EmployeeId, emp.EmployeeName);
}

PaginateAndCountメソッド

指定したSELECTのSQLをページング用のSQLに変換し実行した結果をIList<T>で取得するとともに、ページング用に変換しないSQLで取得できる件数を同時に取得します。つまり、IList<T> と long を要素とするタプルを返します。使用するDBの設定によっては元のSQLに order by 句が指定されている必要があります。
PaginateAndCountメソッドのジェネリックパラメータには基本型、クラス型、タプル型、dynamic型のいずれかを指定できます。ここに指定された型が戻り値のIListの要素の型になります。
タプル型の要素は基本型もしくはクラス型でなければいけません。タプル型の要素に基本型とクラス型が混在する場合は、基本型がクラス型より前に宣言されなければいけません。
第一引数はSQL、第二引数はoffset、第三引数はlimit、第四引数はは問い合わせ条件に利用する匿名型のインスタンスです。

SQLの変換例を示します。SQLは2つに分かれて実行されます。

C# code
var empListAndCount = 
  db.PaginateAndCount<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );
変換され実行されるSQL 1
select 
  * 
from 
  ( select 
      temp_.*, 
      row_number() over( order by Salary) as soma_rownumber_ 
    from 
      ( select EmployeeName from Employee where Salary > @p0 ) as temp_ 
  ) as temp2_ 
where 
  soma_rownumber_ > @p1
  and 
  soma_rownumber_ <= @p2
パラメータ@p0、@p1、@p2 にはそれぞれ 1000M、10、60 がバインドされます。

変換され実行されるSQL 2
select 
  count(*) 
from 
  ( select EmployeeName from Employee where Salary > @p0 ) as t_
パラメータ @p0 には1000M がバインドされます。


さまざまなジェネリックパラメータを用いた例を以下に示します。

例 : ジェネリックパラメータが基本型
var empListAndCount = 
  db.PaginateAndCount<string>(
    "select EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがクラス型
var empListAndCount = 
  db.PaginateAndCount<Employee>(
    "select * from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型
var empListAndCount = 
  db.PaginateAndCount<Tuple<string, decimal>>(
    "select EmployeeName, Salary from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素がクラス型
var deptEmpListAndcount = 
  db.PaginateAndCount<Tuple<Department, Employee>>(
    "select d.*, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by e.Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがタプル型 かつ タプル型の要素が基本型とクラス型の混在
var empListAndCount = 
  db.PaginateAndCount<Tuple<string, Employee>>(
    "select d.DepartmentName, e.* from Employee e inner join Department d on (e.DepartmentId = d.DepartmentId) where e.Salary > /* salary */0 order by e.Salary",
    10,
    50,
    new { salary = 1000M} );

例 : ジェネリックパラメータがdynamic型
var empListAndCount = 
  db.PaginateAndCount<dynamic>(
    "select EmployeeId, EmployeeName from Employee where Salary > /* salary */0 order by Salary",
    10,
    50,
    new { salary = 1000M} );
foreach (emp in empListAndCount.Item1) {
  Console.WriteLine("{0}, {1}", emp.EmployeeId, emp.EmployeeName);
}

Executeメソッド

任意のSQLを指定して結果件数を取得します。例を以下に示します。

例 : 複数件の削除
var rows = 
  db.Execute(
    "delete from Employee where Salary > /* salary */0",
    new { salary = 1000M } );

ExecuteReaderメソッド

SQLの結果セットをハンドリングします。例を以下に示します。

例 : データテーブルへのロード
var table = 
  db.ExecuteReader(
    reader =>
    {
      var t = new DataTable();
      t.Load(reader);
      return t;
    },
    "select * from Employee where Salary > /* salary */0",
    new { salary = 1000M } );

Findメソッド

主キーで一件を検索し、結果をクラス型のインスタンスで取得します。
Findメソッドのジェネリックパラメータにはクラス型を指定できます。ここに指定された型が戻り値の型になります。
ジェネリックパラメータに指定するクラス型のプロパティにはIdAttributeが適切に付与されている必要があります。
Findの第一引数には主キーを渡します。

典型的な検索処理の例を以下に示します。

例 :典型的な検索処理
var emp = db.Find<Employee>(1);

主キーが複数ある場合は、配列やリストとして渡します。例を以下に示します。

例 : 主キーが複数ある場合
var emp = db.Find<Employee>(new []{1, "abc"});

結果が見つからない場合は EntityNotFoundException をスローします。

TryFindメソッド

主キーで一件を検索し、結果をクラス型を要素とするオプション型のインスタンスで取得します。戻り値は、結果がなければ null になります。
TryFindメソッドのジェネリックパラメータにはクラス型を指定できます。ここに指定された型が戻り値の型になります。
ジェネリックパラメータに指定するクラス型のプロパティにはIdAttributeが適切に付与されている必要があります。
TryFindメソッドの第一引数には主キーを渡します。

典型的な検索処理の例を以下に示します。

例 : 典型的な検索処理
var emp = db.TryFind<Employee>(1);

主キーが複数ある場合は、配列やリストとして渡します。例を以下に示します。

例 : 主キーが複数ある場合
var emp = db.TryFind<Employee>(new []{ 1, "abc" });

FindWithVersionメソッド

主キーで一件を検索し、バージョンをチェックしてから結果をクラス型のインスタンスで取得します。
FindWithVersionメソッドのジェネリックパラメータにはクラス型を指定できます。ここに指定された型が戻り値の型になります。
ジェネリックパラメータに指定するクラス型のプロパティにはIdAttributeとVersionAttributeが適切に付与されている必要があります。
FindWithVersionメソッドの第一引数には主キーを、第二引数にはバージョンを渡します。

典型的な検索処理の例を以下に示します。

例 :典型的な検索処理
var emp = db.FindWithVersion<Employee>(1, 0);

主キーが複数ある場合は、配列やリストとして渡します。例を以下に示します。

例 : 主キーが複数ある場合
var emp = db.FindWithVersion<Employee>(new []{ 1, "abc" }, 0);

主キーによる検索で結果が見つからない場合は EntityNotFoundException をスローします。

主キーによる検索で結果が見つかってもバージョンが異なる場合は OptimisticLockException をスローします。

TryFindWithVersionメソッド

主キーで一件を検索し、バージョンをチェックしてから結果をクラス型を要素とするオプション型のインスタンスで取得します。戻り値は、結果がなければ null になります。
TryFindWithVersionメソッドのジェネリックパラメータにはクラス型を指定できます。ここに指定された型が戻り値の型になります。
ジェネリックパラメータに指定するクラス型のプロパティにはIdAttributeとVersionAttributeが適切に付与されている必要があります。
TryFindWithVersionメソッドの第一引数には主キーを、第二引数にはバージョンを渡します。

典型的な検索処理の例を以下に示します。

例 : 典型的な検索処理
var emp = db.TryFindWithVersion<Employee>(1, 0);

主キーが複数ある場合は、配列やリストとして渡します。例を以下に示します。

例 : 主キーが複数ある場合
var emp = db.TryFindWithVersion<Employee>(new []{ 1, "abc" }, 0);

主キーによる検索で結果が見つかってもバージョンが異なる場合は OptimisticLockException をスローします。

Insertメソッド

エンティティに対応する行を挿入します。IdAttributeやVersionAttributeが指定されたエンティティのプロパティは設定に基づき更新されることがあります。
ジェネリックパラメータにはクラス型を指定できます。
一意制約違反が発生した場合、UniqueConstraintExceptionをスローします。

典型的な挿入処理の例を以下に示します。

例 : 典型的な挿入処理
var emp = new Employee { EmployeeId = 0, EmployeeName = "Hoge", VersionNo = 0 };
db.Insert(emp);

2つの引数を持つオーバーロードされたInsertメソッドでは、第二引数にオプションを指定できます。オプションを利用すると次のことが可能になります。
  • INSERT INTO 句から特定のプロパティ(にマッピングされたカラム)を除外する
  • INSERT INTO 句に特定のプロパティ(にマッピングされたカラム)のみを含める
  • INSERT INTO 句から値がNULLであるプロパティ(にマッピングされたカラム)を除外する

挿入処理のオプションは Soma.Core.InsertOpt クラスで表します。

INSERT INTO 句から特定のプロパティ(にマッピングされたカラム)を除外するには、 InsertOptクラスのExcludeプロパティに除外したいプロパティ名を指定します。
指定するのはカラム名ではなく、カラム名にマッピングされたプロパティ名であることに注意してください。
以下に例を示します。

例 : INSERT INTO 句から特定のプロパティを除外する
var emp = new Employee { EmployeeId = 0, EmployeeName = "Hoge", Age = 21, Salary = 200000M, VersionNo = 0 };
db.Insert(emp, new InsertOpt { Exclude = new [] {"Age", "Salary"} } );

INSERT INTO 句に特定のプロパティ(にマッピングされたカラム)のみを含めるには、 InsertOptクラスのIncludeプロパティに除外したいプロパティ名を指定します。
指定するのはカラム名ではなく、カラム名にマッピングされたプロパティ名であることに注意してください。
以下に例を示します。

例 : INSERT INTO 句に特定のプロパティのみを含める
var emp = new Employee { EmployeeId = 0, EmployeeName = "Hoge", Age = 21, Salary = 200000M, VersionNo = 0 };
db.Insert(emp, new InsertOpt { Include = new [] {"EmployeeName"} } );

INSERT INTO 句から値がNULLであるプロパティ(にマッピングされたカラム)を除外するには、InsertOptクラスのExcludeNullプロパティをtrueに設定します。
以下に例を示します。

例 : INSERT INTO 句から値がNULLであるプロパティを除外する
var emp = new Employee { EmployeeId = 0, EmployeeName = "Hoge", Age = null, Salary = null, VersionNo = 0 };
db.Insert(emp, new InsertOpt { ExcludeNull = true } );

Updateメソッド

エンティティに対応する行を更新します。VersionAttributeが指定されたエンティティのプロパティは更新されます。
ジェネリックパラメータにはクラス型を指定できます。
クラス型は主キーカラムに対応するプロパティを持っている必要があります。主キーカラムに対応するプロパティはIdAttributeで指定します。
クラス型がバージョンカラムに対応するプロパティを持つ場合、楽観的排他制御を行います。すなわち、更新件数が0件の場合OptimisticLockExceptionをスローします。バージョンカラムに対応するプロパティはVersionAttributeで指定します。
一意制約違反が発生した場合、UniqueConstraintExceptionをスローします。
クラス型がバージョンカラムに対応するプロパティを持たない場合で更新件数が0件の場合、NoAffectedRowExceptionをスローします。

典型的な更新処理の例を以下に示します。

例 : 典型的な更新処理
var emp = db.Find<Employee>(1);
emp.EmployeeName = "Hoge";
db.Update(emp);

2つの引数を持つオーバーロードされたUpdateメソッドでは、第二引数にオプションを指定できます。オプションを利用すると次のことが可能になります。
  • SET 句から特定のプロパティ(にマッピングされたカラム)を除外する
  • SET 句に特定のプロパティ(にマッピングされたカラム)のみを含める
  • SET 句から値がNULLであるプロパティ(にマッピングされたカラム)を除外する
  • バージョンを無視する

更新処理のオプションは Soma.Core.UpdateOpt クラスで表します。

SET 句から特定のプロパティ(にマッピングされたカラム)を除外するには、 UpdateOptクラスのExcludeプロパティに除外したいプロパティ名を指定します。
指定するのはカラム名ではなく、カラム名にマッピングされたプロパティ名であることに注意してください。
以下に例を示します。

例 : SET 句から特定のプロパティを除外する
var emp = new Employee { EmployeeId = 1, EmployeeName = "Hoge", Age = 21, Salary = 200000M, VersionNo = 1 };
db.Update(emp, new UpdateOpt { Exclude = new [] {"Age", "Salary"} } );

SET 句に特定のプロパティ(にマッピングされたカラム)のみを含めるには、 UpdateOptクラスのIncludeプロパティに除外したいプロパティ名を指定します。
指定するのはカラム名ではなく、カラム名にマッピングされたプロパティ名であることに注意してください。
以下に例を示します。

例 : SET 句に特定のプロパティのみを含める
var emp = new Employee { EmployeeId = 1, EmployeeName = "Hoge", Age = 21, Salary = 200000M, VersionNo = 1 };
db.Update(emp, new UpdateOpt { Include = new [] {"EmployeeName"} } );

SET 句から値がNULLであるプロパティ(にマッピングされたカラム)を除外するには、UpdateOptクラスのExcludeNullプロパティをtrueに設定します。
以下に例を示します。

例 : SET 句から値がNULLであるプロパティを除外する
var emp = new Employee { EmployeeId = 1, EmployeeName = "Hoge", Age = null, Salary = null, VersionNo = 1 };
db.Update(emp, new UpdateOpt { ExcludeNull = true } );

バージョンを無視するには、UpdateOptクラスのIgnoreVersionプロパティをtrueに設定します。
バージョンを無視するとバージョンプロパティにマッピングされたカラムがSET 句と WHERE 句の両方から除外され、OptimisticLockException が発生しなくなります。
以下に例を示します。

例 : バージョンを無視する
var emp = new Employee { EmployeeId = 1, EmployeeName = "Hoge", Age = null, Salary = null, VersionNo = 1 };
db.Update(emp, new UpdateOpt { IgnoreVersion = true } );

Deleteメソッド

エンティティに対応する行を削除します。
ジェネリックパラメータにはクラス型を指定できます。
クラス型は主キーカラムに対応するプロパティを持っている必要があります。主キーカラムに対応するプロパティはIdAttributeで指定します。
クラス型がバージョンカラムに対応するプロパティを持つ場合、楽観的排他制御を行います。すなわち、削除件数が0件の場合OptimisticLockExceptionをスローします。バージョンカラムに対応するプロパティはVersionAttributeで指定します。
クラス型がバージョンカラムに対応するプロパティを持たない場合で削除件数が0件の場合、NoAffectedRowExceptionをスローします。

典型的な削除処理の例を以下に示します。

例 : 典型的な削除処理
var emp = db.Find<Employee>(1);
db.Delete(emp);

2つの引数を持つオーバーロードされたDeleteメソッドでは、第二引数にオプションを指定できます。オプションを利用すると次のことが可能になります。
  • バージョンを無視する

削除処理のオプションは Soma.Core.DeleteOpt クラスで表します。

バージョンを無視するには、DeleteOptクラスのIgnoreVersionプロパティをtrueに設定します。
バージョンを無視するとバージョンプロパティにマッピングされたカラムが WHERE 句から除外され、OptimisticLockException が発生しなくなります。
以下に例を示します。

例 : バージョンを無視する
var emp = db.Find<Employee>(1);
db.Delete(emp, new DeleteOpt { IgnoreVersion = true } );

Callメソッド

ストアドプロシージャを実行します。
一意制約違反が発生した場合、UniqueConstraintExceptionをスローします。
ストアドプロシージャとエンティティのマッピング方法については マッピング を参照してください。

典型的なストアドプロシージャ呼び出しを以下に示します。

例 : 典型的なストアドプロシージャ呼び出し
var procedure = new ProcMultiParams { Param1 = 1, Param2= 2, Param3 = 0 };
db.Call(procedure);

Last edited Aug 21, 2011 at 3:06 AM by toshihiro, version 24

Comments

No comments yet.