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.

dapper

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.

Dapper

Dapper projeye eklendikten sonra referanslar kısmına bakıldığında, aşağıdaki dosyadan başka birşey gözükmemektedir:)

dapperRef

Ş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.

Mvc projesine aşağıdaki kütüpahaneler eklenir.

Web.config dosyasına tanımlanan “connection string” local bir makina için aşağıdaki gibidir.

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.

GetYorumByHaber: MsSql tarafında haber’e ait yorumları çekmek için yazılan procedure.

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.

SaveCommand: Haber’e ait yorumun kaydedilmesi amacı ile yazılan procedure.

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.

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.

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: 

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

22 Cevaplar

  1. Yiğit dedi ki:

    Hocam elinize saglik.
    Benim icin cok faydali bir teknoloji ogrenimi oldu.

    Tesekkurler.

  2. Kaan dedi ki:

    Anladığım kadarıyla githubtaki readmesini incelediğimde .Nette Ado.Net karşılığına geliyor diyebiliriz. Query lerde linq’dan farklı olarak syntax biraz farklı görünüyor. Onun dışında multi thread işlemlerde EF de de batch Request yapabiliyorsunuz, burada bir farkı göremedim. Asıl sorum micro ORM’ler gerçekten büyük projelerde de beklenen performansı sağlıyor mu?

    • borsoft dedi ki:

      Selam Kaan,

      Queryler bildiğin MsSql Query. Ve soruna gelince evet zaten büyük projelerde performans amaçlı kesinlikle kullanılıyor. Mesela stackoverflow.com bunlardan biri.
      Bence yeterince güven verici.

      İyi çalışmalar.

  3. Hüseyin Özgül dedi ki:

    Merhabalar,

    Daha önce test etme imkanı bulduğum Uni.ORM yi de bir inceleyip yorum yaparsanız sevinirim.

  4. Romario dedi ki:

    StackExchange kullanıyorsa muhakkak kullanışlı birşeydir. Görüldüğü kadarıyla DB bağlantısı ve sorgular için kodlama elle yapılan , onun haricindeki ORM işlemlerini halleden birşey.

    Bu arada Benchmark listesinde Devexpress dahil edilmemiş gibi görünüyor. Devexpress’in eXpress Persistent Objects’inde (XPO) DB bağlantısı ve sorgular XPO’nun içinde gömülü.

  5. Faruk Yeşil dedi ki:

    Merhabalar,
    Performans gibi sıkıntınız varsa, Dapper güzel bir seçenek.
    İyi çalışmalar.

  6. Merhaba,

    Bloğunuzdaki her değerli yazıdan faydalanmaya çalışıyorum. Bu projede şunu yapabiliyor muyuz? Mesela bir güncelleme paketindeki execute sql kodlarını programın kendi veritabanına dump edebiliyor muyuz?

    Mesela mysql source çıktısından sqlite a veya sqlite dan sqlite a aktarabiliyor muyuz?

    Şimdiden çok teşekkürler.

    • borsoft dedi ki:

      Selamlar Halil,
      Öncelikle güzel yorumun için teşekkürler.
      Sadece Dapper kullanarak yukarıda yazdığın işleri doğrudan yapamazsın. Ya bu kümülatif dataları MSSql üzerinden atacaksın ya da bunlar için bir app yazıp tüm data kümesini istersen dapper kullanarak atacaksın.

      Yanlış anlamadı isem senin aradığın cevap bu.
      İyi çalışmalar.

      • Cevabınız için çok teşekkürler.

        Peki güncelleme paketlerini işleyebilmem için nasıl bir yöntem kullanmalıyım sizce? Yani güncelleme verirken 40 mb lik bir güncelleme paketinde database’i tekrardan güncelletmek yerine sadece eklediğim veya güncellediğim sql kodlarını gönderip güncelletebileceğim bir yöntem yok mudur? Tecrübeleriniz benim için çok değerli lütfen yardımcı olursanız ok sevinirim.

  7. Hasan Aksu dedi ki:

    sql sp execute ettiğiniz için hızlı olduğunu düşünüyorsunuz.

    Context.Database.SqlQuery(procName, parametters).ToList();
    SqlConnection.Query(storedProcedure, param: (object)param, commandType: CommandType.StoredProcedure);

    bu işlemi kullandığımızda aynı sp için geriye 100bin kayıt dönen bir işlemde.
    dapper 244ms
    entityframework 349ms de sonuç veriyor.
    Yanlız; sayfaya yeni den f5 yaptığınızda
    dapper 244ms
    entityframework 156ms de cevap veriyor.
    Bu işlemler using blogları içinde yapılmıştır.

    malum entityframework ilk yüklemede bütün context sınıfını ve mapping işlemlerini ayağa kaldırması gerekiyor.

    Eğer sitenizin tamamını sp ler üzerine inşa edecekseniz sorun yok dapper kullanın,
    ama böyle bir durumda neden Ado.Net kullanmıyorum sorusu insanın aklına geliyor.
    Eğer sql queryler yazarım joinleri string şekilde oluştururum diyorsanız injecttion, anti xss kounları akla geliyor.

    • borsoft dedi ki:

      Öncelikle Selam Hasan,

      Yorumunda bir soru göremedim. Sanırım fikirlerini belirttin. Ben de düşüncelerimi söyliyim.
      Senin yorumlarından yola çıkarak, insanın aklına türlü türlü şeyler geliyor :)

      İşin şakası bir yana dapper, linq ile çalışır iken Ado.Net malesef çalışamaz. Ama sizin de tahmin edebileceğiniz gibi Ado.Net daha performanslıdır. Kısaca tamamen seçim meselesi.
      Dapper Sql procedure olmadan da çok performanslı çalışır. Queryler code içerisinde dinamik olarak yaratılabilir. Ben bir çok projede gözle görülebilir bir fark gördüm. Procedure ile kullanmada daha performanslı olmasının nedeni Dapperla alakalı değil, Sql tarafında Execution planın çıkarılmasıdır.
      Derleme zamanında, büyük yüklerde ve sizinde belirtiğiniz gibi sunucu ilk ayağa kalkarken çok başarılıdır. Son olarak Usingler arasında kullanmak tamammen GC için yapılan memory managment için performans sağlayan bir Deconstruction yapıdır. Dapper’ın veya Entityframework’ün hızına etkisi olmayan bir yapıdır.

      Hızlı düşündüğüm gibi bir kanı yanlıştır. Düşündüğüm şeylerin makalesini en azından bu makalede yazmadım. Tamamen gurupların testlerinden yola çıkarak ve ben de test ederek yazdım. Ayrıca Stack Overflow gibi inanılmaz yük alan portallar kullanıyorsa vardır bir bildikleri diye düşünüyorum.

      İyi çalışmalar.

  8. kerim Şahin dedi ki:

    Bora Bey Merhaba , bir gün sizinle tanışmak çok istiyorum. Umarım o gün bir gün gelir :). Bu konuda drapper ile araştırma yapmaya başladım. Entity göre daha hızlı olduğu için. Code First olarak biraz zayıfım veritabani oluşturmada. Tümüyle hakim değilim. Entity kullanırken new add diyerek data kısmından managament studio da olusturdugum veritabanının model dosyasını projeye ekliyordum. Drapper kullanırkende veritabanının modelini ekleyerek yapabilir miyiz ? Bu bir sorun teşkil edebilir mi daha sonradan ? Ya da drapperın sağladığı hıza bir karşı etki sağlar mı ?

    • borsoft dedi ki:

      Selamlar Kerim,
      Öncelikle güzel sözlerin için teşekkür ederim. Bir de drapper değil dapper :) Tanışmak kolay. Gel bir seminerime tanışalım:) Dapper’ı stackoverflow kullanıyor. Dezavantajı yazılımcıya yazarken daha çok iş çıkarması dışında yok. Mapper işleri biraz zahmetli. Hızı tartışılmaz. Şiddet ile tavsiye ederim. Linq de yazabiliyorsun. Yoksa Ado.Net daha da hızlı. Ama link kullanamazsın. Code First arıyor isen bu dapper’da yok. Bilgine .

      İyi yıllar.
      Bora.
      Hoşçakal.

      • Kerim Şahin dedi ki:

        Merhaba tekrar, boş vakitlerimde dapper (“drapper :)” ) hakkında denemeler yapıyorum öğrenmek için ve bu konu hakkında bir soru daha sormak istiyorum. Sql Server Managament üzerinden veritabanını oluşturup sonradan proje üzerinde add > new item > data kısmından Ado.net entity data model kısmını seçerek ilk seçenek olan EF Designer From Database ekleyerek projede Entity Freamwork rahatlıkla kullanabiliyorum. Hız farklarını görünce ne yazıkkı soğudum oldukçada harika yazılıyordu EF ile. Yapacak birşeyim yok ya dapper yada ado.net ile devam edecem artık. Şimdi Mvc öğrenmeye yeni başladım fakat models klasör içerisinde veritabanında oluşturduğum tabloları tekrar projede class olarak yazmak yerine EF de olduğu gibi sağ tık > add > new item > data alanından Entity data model kısmına baktığımızda
        ( http://prntscr.com/i55ud4 ) resimdeki gibi 3 seçenek daha var ingilizcem çat pat ama deneyerek görerek öğrenebiliyorum. Code First from Database kısmını seçtiğimizde sql de oluşturduğumuz tabloları class olarak models klasorune ekliyor. ( http://prntscr.com/i55ria ). Bu şekilde yaptığımızda References kısmına EntityFreamwork ve EntityFreamwork.SqlServer dll dosyalarını yine de ekliyor. Bu şekilde de class ları ekleyip kullanamaz mıyız ? Dezavantajı olur mu ? Yani bunu yaptığımda “Dapper kullanmanın ne anlamı kaldı ?” sorusuyla karşı karşıya kalır mıyım ? Tabi projede class oluşturup veritabanını otomatik olarak oluşturma seçenekleride var ama ben bu konu hakkında öğrenmek istiyorum. Entity Data Model alanındaki 3 seçenekten biri ile bu şekilde class ları hazır oluşturup kullanabilir miyim ? Yani (her zamanki gibi uzatıyorum.) ekmek fırınında ocağı yakıp hamuru içine atıp pişirip cıkartıp gidip satmak değilde fırından hazır pişmiş ekmekleri gidip saymak istiyorum. Zaman kazanmak ve olası insan hatasından kaçınmak için ? Seminerinize katıldığımda Drapper dediğimde hatırlamanız duasıyla selamlar.

        • borsoft dedi ki:

          Selamlar,
          Dapper’da Mapleme için, toolar var. İncele derim. Malesef CodeFirst kullandın mı EntityFramework’de gelir. Mantıklı değil.

          İyi çalışmalar.

  9. Osman dedi ki:

    Merhaba,

    var haberList = model.Read().ToList();
    var kategoriList = model.Read().ToList();

    kısmını anlayamadım ben ve çözemedim denemelerimde, join sorgusunda nasıl iki farklı entitylist olara kgöndürebiliriz ?

    • borsoft dedi ki:

      Selamlar Osman,
      Makalede de belirtiğim gibi sonuç, çoklu query(QueryMultiple()) yani 2 farklı tablo dönüyor.

      1.) Tablo : select H.Baslik,H.Detay,K.Ad as KategoriAdı
      2.) Tablo : Select * from Kategoris

      var haberList = model.Read().ToList(); ==> 1.Tablo sonucunu çekiyor.
      var kategoriList = model.Read().ToList(); ==> 2. Tablo sonucunu çekiyor.

      İyi çalışmalar.

  10. Kerim Şahin dedi ki:

    Merhaba Bora Bey, api den gelen Json listesini döngü kullanmadan insert etmemiz mümkün mü dapper ile. Json listesi içinde de iç içe listeler mevcut durumdayken iç içe foreach kullandığımda yaklaşık 9 dk da kaydetme işlemi gerçekleştiriyor. iç içe 3 liste şeklinde dapper da daha kısa sürede kaydetmek için bir yöntem var mı ?

  11. Kaan Acar dedi ki:

    Dapper maalesef 2 den fazla ilişkili tablo kullanıldığında çok da yeterli olmamakta gördüğüm. örnek Kategori>Ürün>Ürün Menşei tarzı bir yapıda dapper da bir çözüm yok.

  12. Kaşeci dedi ki:

    Çok teşekkürler

borsoft için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak.