Dapper Nedir?
Selamlar;
Bugün Micro Ormler içinde en hızlısından biri olan Dapper’ı bir Mvc projesi ile inceleyeceğiz. Aşağıda hızı ile ilgili performans testi gözükmektedir.
Genelde Orm araçları biraz hantal çalışır. Özellikle yoğun trafik alan portallarda pek de tercih edilmez. Ancak bu gibi durumlarda bir “Micro Orm” bir çok soruna çözüm olabilir. Örneğin “Dapper“sadece tek bir “Dll”dir. Çok hızlıdır. LightWeight dir. Yani, ne mapping yapmak için bir ara yüzü vardır ne de herhangi bir konfigurasyon dosyasına ihtiyaç duymaktadır. Kısaca basit ve çok hızlıdır. Ayrıca bize aynı entity framework’de olduğun gibi kolayca Query yazma olanağı sağlamaktadır. Bana en güven veren durumlardan biri de “Stack Overflow” geliştiricileri tarafından yazılmış olan bir Orm Tool’u olmasıdır.
Nuget’den aşağıdaki paket indirilerek kolaylıkla “Dapper” projeye eklenebilir.
Nuget’den aşağıdaki paket indirilerek kolaylıkla “Dapper” projeye eklenebilir.
Dapper projeye eklendikten sonra referanslar kısmına bakıldığında, aşağıdaki dosyadan başka birşey gözükmemektedir:)
Şimdi gelin pocolarımızı yani Data Modellerimizi oluşturalım. Yorum ve Kategori sınıfları aşağıdaki gibi tanımlanır. Bu sınıflar “HaberContext” adındaki bir MsSql database’deki tablolara karşılık gelmektedir. Dapper’da işlem yapılacak DB’deki tabloların sınıf karşılıkları ilgili projede tek tek tanımlanmalıdır.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Kategori
{
public int id { get; set; }
public string Ad { get; set; }
}
public class Yorum
{
public int id { get; set; }
public string Ad { get; set; }
public string Detay { get; set; }
public DateTime Tarih { get; set; }
public int Haber_id { get; set; }
}
|
Mvc projesine aşağıdaki kütüpahaneler eklenir.
1
2
3
4
5
6
7
8
|
using System;
using System.Linq;
using System.Web.Mvc;
using Dapper;
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Data;
|
Web.config dosyasına tanımlanan “connection string” local bir makina için aşağıdaki gibidir.
1
2
3
4
|
<connectionStrings>
<add name=“HaberContext” connectionString=“Server=(local);Database=HaberContext;
Trusted_Connection=True;” providerName=“System.Data.SqlClient” />
</connectionStrings>
|
Dapper’da öncelikle bir “SqlConnection” tanımlanmalıdır. Daha sonra aşağıdaki örnek de olduğu gibi ilgili connection içinde istenen “Query”ler çekilebilir. İlgili örnekte “Join” işlemleri yapılarak 2 farklı tablodan bilgi çekilebilir. Ayrıca 2 farklı sorgu ile birden fazla query result dönülebilir. Çoklu sorgu çekmek için Dapper’da “QueryMultiple()” methodu kullanılır. Ayrıca asenkron yapıyı da “Dapper” desteklemektedir. Dönen farklı query resultlar, herbir Query sonucu için “Read()” methodu çalıştırılarak sıra ile alınabilir. Örneğin aşağıdaki örnekte “Habers” ve “Kategoris” tablolarından ayrı ayrı sorgular çekilmiştir.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public async Task<ActionResult> Index()
{
using (var sqlConnection= new SqlConnection(ConfigurationManager.ConnectionStrings[“HaberContext”].ToString()))
{
var model = await sqlConnection.QueryMultipleAsync(“select H.Baslik,H.Detay,”+
“K.Ad as KategoriAdı from Habers as H join Kategoris as K on H.Kategori_id=K.id “+
“Select * from Kategoris”);
var haberList = model.Read().ToList();
var kategoriList = model.Read().ToList();
return View(model);
}
|
GetYorumByHaber: MsSql tarafında haber’e ait yorumları çekmek için yazılan procedure.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
USE [HaberContext]
GO
/****** Object: StoredProcedure [dbo].[GetYorumByHaber] Script Date: 03/21/2016 22:45:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[GetYorumByHaber]
@HaberID int
as
select * from Yorums where Haber_id=@HaberID
GO
|
Dapper’da Procedure Desteği: Aşağıda görüldüğü gibi “GetYorumHaber” procedure ile girilen “HaberID” parametresine göre ilgili yorumlar asenkron olarak çekilmektedir. Ayrıca procedure’ün dönüş tipinin “<Yorum>” olduğu aşağıda görüldüğü gibi belirtilmiştir.
1
2
3
4
5
6
7
8
|
//Procedure
var yorumlar = await sqlConnection.QueryAsync<Yorum>(“GetYorumByHaber”,
new { HaberID = 1 }, commandType: System.Data.CommandType.StoredProcedure);
foreach (Yorum yrm in yorumlar)
{
//İlgili yorumların çekilip işlem yapılacağı kısım
var i = 0;
}
|
SaveCommand: Haber’e ait yorumun kaydedilmesi amacı ile yazılan procedure.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
USE [HaberContext]
GO
/****** Object: StoredProcedure [dbo].[SaveCommand] Script Date: 03/21/2016 22:47:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[SaveCommand]
@Id int output,
@Ad varchar(20),
@Detay varchar(50),
@Haber_id int,
@Tarih datetime
as
insert into Yorums(Ad,Detay,Haber_id,Tarih)values(@Ad,@Detay,@Haber_id,@Tarih)
set @Id=SCOPE_IDENTITY()
GO
|
Procedure’e Dynamic Parameter Tanımlama: “Dynamic” parametre tanımı ile procedure’e yeni oluşturulan “Yorum” sınıfı parametre olarak atanır. “Parametre”‘ye atanan her bir değişkenin data tipi “DbType” ile belirtildikten sonra “@” ile başlıyan procedure’deki adı ile ilgili isim atanır.”@Id” parametresi “OutPut” parametre olarak atanmıştır. Yeni oluşturulan yorum sınıfı “SaveCommand” procedure ile kaydedilmiş ve bu yeni “Yorum” kaydına ait ID değeri “parameter.Get<int>(‘@id’)” methodu ile çekilerek, yeni oluşturulan yorum sınıfının “id” değerine atanmıştır.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//Dynamic Parameter
Yorum yrm2 = new Yorum() { Ad = “Bora Kaşmer”, Detay = “Güzel Bir Dapper Örneği”,
Tarih = DateTime.Today, Haber_id = 2 };
var parameter = new DynamicParameters();
parameter.Add(“@Id”, yrm2.id, dbType: DbType.Int32,
direction: ParameterDirection.InputOutput);
parameter.Add(“@Ad”, yrm2.Ad);
parameter.Add(“@Detay”, yrm2.Detay);
parameter.Add(“@Haber_id”, yrm2.Haber_id, dbType: DbType.Int32);
parameter.Add(“@Tarih”, yrm2.Tarih, dbType: DbType.DateTime);
sqlConnection.Execute(“SaveCommand”, parameter, commandType: CommandType.StoredProcedure);
//Yeni İnsert edilen Yoruma ait ID çekilir.
yrm2.id = parameter.Get<int>(“@Id”);
|
Dapper’da Insert: “Insert” cümleciği ile “Yorum” sınıfına ait propertyler “@” işareti ile başlıyan değişkenler ile tanımlanmış alanlara parametre olarak yeni oluşturulan yorum sınıfı(yrm3) atanmıştır. Son olarak “Select SCOPE_IDENTITY” ile insert edilen en son yorum datasının “@@identity” degeri yani “id” kolonu geri dönülür.
1
2
3
4
5
|
Yorum yrm3 = new Yorum() { Ad = “Engin Polat”, Detay = “King Of Orm”,
Tarih = DateTime.Today, Haber_id = 3 };
int lastYorumID = sqlConnection.Query<int>(“Insert into Yorums(Ad,Detay,Haber_id,Tarih) “+
“values(@Ad,@Detay,@Haber_id,@Tarih)” +
” SELECT CAST(SCOPE_IDENTITY() as int)”, yrm3).Single();
|
Böylece gerçekten çok hızlı olan Micro Orm Dapper’ı hep beraber inceledik. Pocoların tanımlanması ve yazılacak Queryler biraz daha zahmetli olmasına karşılık sadeliği ve performansı ile kesinlikle tercih edilebilir.
Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Source:
- https://dapper-tutorial.net
- https://github.com/StackExchange/Dapper
- https://www.borakasmer.com/dapper-nedir/