8. update Person
set
Age = @Age
where Name = @Name
and Sex = @Sex
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public int Sex { get; set; }
}
こんな感じになったら嬉しい
14. [Table("Person", Schema = "dbo")] //--- テーブル名の指定
public class Person
{
[Key] //--- 主キー
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //--- 自動採番
public int Id { get; set; }
[Required] //--- NotNull
[Column("名前")] //--- 列名の指定
public string Name { get; set; }
[Sequence("AgeSeq", Schema = "dbo")] //--- シーケンスの利用 (Oracleなどで)
public int? Age { get; set; }
[NotMapped] //--- マッピングしない
public int Sex { get; set; }
}
属性によるマッピング型定義
Code Firstと
ほぼ同様
15. public sealed class TableMappingInfo
{
public Type Type { get; } //--- マッピングするクラスの型
public string Schema { get; } //--- テーブルのスキーマ名
public string Name { get; } //--- テーブル名
public IReadOnlyList<ColumnMappingInfo> Columns { get; } //--- 列マッピング情報
public static TableMappingInfo Create<T>(){ … }; //--- メタデータの取得
}
マッピングメタデータの提供 #1
キャッシュ
が効くので
高速
16. public sealed class ColumnMappingInfo
{
public string PropertyName { get; } //--- プロパティ名
public Type PropertyType { get; } //--- プロパティのデータ型
public string ColumnName { get; } //--- 列名
public DbType ColumnType { get; } //--- 列のデータ型
public bool IsPrimaryKey { get; } //--- 主キーかどうか
public bool IsNullable { get; } //--- NULL許可かどうか
public bool IsIdentity { get; } //--- 自動採番をするどうか
public SequenceMappingInfo Sequence { get; } //--- 設定されているシーケンス情報
}
マッピングメタデータの提供 #2
17. public sealed class SequenceMappingInfo
{
public string Schema { get; } //--- シーケンスのスキーマ名
public string Name { get; } //--- シーケンス名
}
マッピングメタデータの提供 #3
18. //--- 指定の列のみを対象として全レコード取得
var sql = PrimitiveSql.CreateSelect<Person>(x => x.Id, x => x.Name);
/*
select
Id as Id,
名前 as Name
from dbo.Person
*/
プリミティブなSQLの生成 #1
指定がない
場合は
全列が対象
19. //--- 指定の列のみを対象として全レコードを更新
var sql = PrimitiveSql.CreateUpdate<Person>(DbKind.SqlServer, x => x.Name);
/*
update dbo.Person
set
名前 = @Name
*/
プリミティブなSQLの生成 #2
Bind変数の
接頭辞の
決定に必要
指定がない
場合は
全列が対象
21. //--- 全件取得
var p1 = connection.Select<Person>();
//--- Id, Name 列に絞って全件取得
var p2 = connection.Select<Person>(x => x.Id, x => x.Name);
//--- Id = 3 のレコードのみ取得
var p3 = connection.Select<Person>(x => x.Id == 3);
//--- Id > 3 のレコードを Id, Name 列に絞って取得
var p4 = connection.Select<Person>(x => x.Id > 3, x => x.Id, x => x.Name);
レコードの取得
.Select<T>
22. //--- 指定されたデータを挿入
var p5 = connection.Insert(new Person { Name = "xin9le", Age = 30 });
//--- 複数のレコードでもOK
var p6 = connection.Insert(new []
{
new Person { Name = "yoshiki", Age= 49, },
new Person { Name = "suzuki", Age= 30, },
new Person { Name = "anders", Age= 54, },
});
レコード挿入
.Insert<T>
23. //--- Age = 30 のレコードの Name 列を更新
var p7 = connection.Update
(
new Person { Name = “xin9le" },
x => x.Age == 30, //--- 指定しなければ全レコード更新
x => x.Name //--- 指定がなければ全列更新
);
レコード更新
.Update<T>
24. //--- 全レコード削除
var p8 = connection.Delete<Person>();
//--- 年齢が30歳でないレコードを削除
var p9 = connection.Delete<Person>(x => x.Age != 30);
//--- テーブルの切り捨て
var p10 = connection.Truncate<Person>();
レコード削除
.Delete<T>
.Truncate<T>
25. //--- メソッド名に ‘Async’ を付けるだけ
var p1 = await connection.SelectAsync<Person>();
var p2 = await connection.InsertAsync(new Person { Name = "xin9le" });
var p3 = await connection.UpdateAsync(new Person { Name = "xin9le" });
var p4 = await connection.DeleteAsync<Person>();
もちろん非同期版も
実際に非同期処理になるかは各DBプロバイダーに依存する
26. Simple = Speed + Power
Dapperの強みをそのままに、select * などの決まった手間を軽減
たった1文で書けるDBアクセス
サポートしていない構文
inner join / left join / order by / group by / サブクエリー (etc.)
やり過ぎは複雑さの増大と自由度の低下を招く
シンプルに、そしてカジュアルに