Entity Framework ile linq dynamic kullanımı

11 Aralık 2015 3 dk okuma süresi 106 okunma

Aşağıdaki resimdeki gibi bir tablolarınız olduğunu varsayın. Bu gibi tablolarda arama yapmak kod tarafında oldukça zahmetli oluyor. Neden diyecek olursanız hangi kolona göre arama yapıldı tek tek if/else veya switch/case yazmaktan bıraksınız. Bu nedenle bu gibi durumlarda dinamik aramalar çok daha kolay ve kısa kod ile işinizi görür.

Bunun html çıktısı da aşağıdaki gibi.

Normalde birçok kişinin yaptığı şey ilk olarak veriyi çekmek ve sonra tek tek filtrelemeyi yapmaktır. Malum bu da performansı ciddi etkiler. Bu nedenle linq dynamic kurtarıcınız olabilir. İlk olarak Nuget ile Linq Dynamic'i yüklemeniz gerekiyor. Basit olarak kullanımına ScuttGu'nun blog yazısından görebilirsiniz. Ben size biraz daha detaylı olarak göstereceğim.

Elinizde siparişler tablonuz olsun. Yapısı su şekilde olabilir.

Siparişleri listelediğinizi ve yukarıdaki gibi (ilk resim) her kolon için bir arama input'unuz olduğunu varsayın. Bu şekilde sipariş, ürün (normalde birden fazla olduğundan ürünler bir tıklama ile popup veya detay sayfasında listelenir, ama biz tek ürün olduğunu düşünelim) ve kullanıcı bilgilerini listelediğinizi düşünün.

Normalde arama için yazacağınız kod şekilde olurdu.

var siparisler = db.Siparisler
    .Where(x => x.Aktif == true && x.Tarih >= DateTime.Now)
    .Include(x => x.SiparisDetaylari)
    .Include(x => x.Kullanicilar)
    .Include(x => x.Urunler)
    .Include(x => x.Urunler.Select(c=>c.UrunKategorileri))
    .ToList();
// urun adina ve kullanici adina gore arama
if (!string.IsNullOrWhiteSpace(urunAdi))
    siparisler = siparisler.Where(x => x.Urunler.Any(c => c.UrunAdi.Contains(urunAdi))).ToList();
if (!string.IsNullOrWhiteSpace(kullaniciAdi))
    siparisler = siparisler.Where(x => x.Kullanicilar.Any(c => c.KullaniciAdi.Contains(kullaniciAdi))).ToList();

Bu şekilde bir sürü sayfanız olduğunu düşünürseniz oldukça fazla iş yükü çıkar. Her sayfada özel kod yazmak durumunda kalırsınız. Fakat linq dynamic ile bu iş yükünden kolayca kurtulabilirsiniz. Linq dynamic sayesinde where koşuluna string olarak ifade yazabiliyorsunuz.

Yani yukarıda ürün adı ve kullanıcı adı ile arama yaptığımız yeri tek satırda halledebiliyoruz.Ki bildiğiniz gibi include kısmına da string ifade yazabiliyoruz. Şöyleki;

var siparisler = db.Siparisler
    .Where("Siparisler.Aktif=true && Siparisler.Tarih>=" + DateTime.Now + " && Siparisler.Any(SiparisDetaylari.UrunAdi.Contains(" + urunAdi + ")) && Siparisler.Any(Kullanicilar.KullaniciAdi.Contains(" + kullaniciAdi + "))")
    .Include("SiparisDetaylari")
    .Include("Kullanicilar")
    .Include("Urunler")
    .Include("Urunler.UrunKategorileri")
    .ToList();

Child collection'lar içerisinde arama yaparken tıpkı lambda expression'da olduğu gibi any ifadesini kullanıyoruz.

Yine aynı şekilde OrderBy ifadesini de string olarak yazabiliyoruz.

var siparisler = db.Siparisler
    .Where("Siparisler.Aktif=true")
    .OrderBy("Siparisler.Tarih ASC")
    .ToList()

Yukarıdaki html çıktısında "data-column", "data-href", "data-type" gibi bazı attribute'lar göreceksiniz. Ben bunları javascript ile controller'a gönderiyorum. Controller gelen verilere göre neleri neye göre araması gerektiğini anlıyor ve arama kısmı dinamikleşmiş oluyor. Bu şekilde yığınla kod yazmak zorunda kalmıyorum. Bununla ilgili bir örneği daha sonra yapıp sizlerle paylaşacağım.

Yazılarıma abone olmak ister misiniz?
Spam yapılmaz, sadece bildirim amaçlıdır. İstediğiniz zaman abonelikten çıkabilirsiniz.
İlginizi çekebilecek diğer yazılar.
VS2015'in 3. update'ini yaptıktan sonra asp.net core web uygulaması yaratmak istediğimde şu şekilde bir hata ile karşılaştım. "Exception : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)". Çözümü oldukça basit.

Entity framework code first kullanıyorsanız ve inheritance yapıp yeni bir class yarattığınızda bunun gibi bir hata alırsınız. Bunun nedeni fluent api'nin inheritance yapılan class ile ana class'ın map yapmaya çalışması ve ilgili kolonu veritabanında bulamamasıdır. Çözümü ise inherit olmuş class'a [NotMapped] DataAnnotations attribute'unu eklemek.

Asp.Net Mvc ile recursive nasıl yazılır, @helper veya HtmlHelper kullanarak recursive fonksiyon yazmak, Asp.Net MVC View recursive fonksiyon nasıl yazılır?