Dapper是一個輕型的ORM類。代碼就一個SqlMapper.cs文件,主要是IDbConnection的擴展方法,編譯后就40K的一個很小的dll。官方站點http://code.google.com/p/dapper-dot-net/ ,也可以通過Nuget進行安裝
- Dapper很快。Dapper的速度接近與IDataReader。
- Dapper支持主流數據庫 Mysql,SqlLite,Mssql2000,Mssql2005,Oracle等一系列的數據庫
- 支持多表並聯的對象。支持一對多 多對多的關系,並且沒侵入性。
- 原理通過Emit反射IDataReader的序列隊列,來快速的得到和產生對象
- Dapper語法十分簡單。並且無須遷就數據庫的設計
Query()方法:
Query()是IDbConnection擴展方法並且重載了,從數據庫里提取信息,並用來填充我們的業務對象模型。
var counters = new List<Tuple<int, PerformanceCounter>>();
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlDiagnosticsDb"].ConnectionString))
{
conn.Open();
string sql = string.Format("select Id,ServiceName,CategoryName,CounterName,InstanceName from service_counters where MachineName='{0}'",machineName);
foreach (var counter in conn.Query<ServiceCounter>(sql))
{
logger.InfoFormat(@"Creating performance counter: {0}\{1}\{2}\{3}", counter.MachineName ?? ".", counter.CategoryName,
counter.CounterName, counter.InstanceName);
var perfCounter = new PerformanceCounter(counter.CategoryName, counter.CounterName, counter.InstanceName, counter.MachineName ?? ".");
counters.Add(new Tuple<int, PerformanceCounter>(counter.Id, perfCounter));
// first value doesn't matter so we should call the counter at least once
try { perfCounter.NextValue(); }
catch { }
}
}
下面是ServiceCounter的定義
public class ServiceCounter
{
public int Id { get; set; }
public String ServiceName { get; set; }
public String MachineName { get; set; }
public String CategoryName { get; set; }
public String CounterName { get; set; }
public String InstanceName { get; set; }
public String DisplayName { get; set; }
public String DisplayType { get; set; }
public override String ToString()
{
return String.Format(@"{0}\{1}\{2}\{3}", MachineName ?? ".", CategoryName, CounterName, InstanceName);
}
}
Dapper也可以加載填充嵌套對象,考慮這樣一種情形,考慮到新聞的類別屬性,返回類別對象。
1,在填充嵌套對象的時候,只好執行ToList<>方法,否則回報ExecuteReader 要求已打開且可用的連接。連接的當前狀態為已關閉,而單個對象不會報錯,估計是using結束后關閉了連接,而嵌套對象在map的時候又執行了ExecuteReader,只好在using結束之前返回list集合。
2,嵌套對象的參數是比較多的,主要是前兩個參數,其它參數沒用可以設置為null。特別要注意的是splitOn,這個參數不能為空,否則會報對象為引用的錯誤。【splitOn參數的意思是讀取第二個對象的的分割列,從哪個列起開始讀取第二個對象,如果表里的自增長列都為Id,可以設置這個參數為”Id”】.
Execute方法:
正如Query方法是檢索數據的,Execute方法不會檢索數據,它與Query方法非常相似,但它總返回總數(受影響的行數),而不是一個對象集合【如:insert update和delete】.
private void SaveServiceSnapshots(IEnumerable<ServiceCounterSnapshot> snapshots)
{
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlDiagnosticsDb"].ConnectionString))
{
conn.Open();
foreach (var snapshot in snapshots)
{
// insert new snapshot to the database
conn.Execute(
@"insert into service_counter_snapshots(ServiceCounterId,SnapshotMachineName,CreationTimeUtc,ServiceCounterValue) values (
@ServiceCounterId,@SnapshotMachineName,@CreationTimeUtc,@ServiceCounterValue)", snapshot);
}
}
}
ServiceCounterSnapshot的定義如下:
public class ServiceCounterSnapshot
{
public int Id { get; set; }
public int ServiceCounterId { get; set; }
/// <summary>
/// Machine on which the snapshot was taken.
/// </summary>
public String SnapshotMachineName { get; set; }
public DateTime CreationTimeUtc { get; set; }
public float? ServiceCounterValue { get; set; }
}