Asp.NET Core WEB API – OData Query Options

Merhaba,

Bir önceki Asp.NET Core Web API Uygulamasına OData Implementasyonu başlıklı yazımızda bir Asp.NET Core Web API uygulamasına OData implemantasyonunun nasıl gerçekleştirildiğini incelemiştik. Bu içeriğimizde ise serverdan dönecek data miktarını kontrol etmemize imkan verecek olan OData Query Options yapılanmasını inceleyeceğiz.

OData Query Options Nedir?

OData Query Options temel olarak, kullanıcı tarafından url üzerinden yapılan veri sorgulamalarında(delete hariç) üretilen datanın kullanıcıya gönderilmeden önce filtrelenmesini, sıralanmasını vs. gibi işlemlere tabii tutularak yapılandırılmasını sağlayan seçeneklerdir.

OData Query Options; ‘System Query Options’, ‘Custom Query Options’ ve ‘Parameter Aliases’ olmak üzere üçe ayrılmaktadır. Hangi kategoriden olursa olsun seçenekler aşağıdaki prototipte olduğu gibi url üzerinde sorguya eklenmektedir.

https://localhost:5001/odata/{controller_name}?${options}={value}

Şimdi sırasıyla bu seçenekleri inceleyelim.

System Query Options

URL üzerinden yapılan sorgulama neticesinde döndürülecek olan data üzerinde filtreleme, seçme, sıralama gibi işlemler yapan, eleman adedini hesaplama, belirtilen adet kadarını ayıklama yahut görmezden gelme gibi eylemlerde bulunan ve navigation propertyler üzerinden fiziksel ilişkiye sahip olan diğer tablolarıda sorgulayabilmemizi sağlayan seçeneklerdir.

  • $filter
    Verilerin filtrelenmesini sağlar. ‘Karşılaştırma’, ‘Mantıksal’, ‘Aritmatik’ ve ‘Fonksiyonel’ operatörlerden oluşmaktadır. Belirtilen ifadelerle yapılan işlemler neticesinde sonuç olarak true dönen öğeler sonuca eklenecektir.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.Filter();
                });
    

    Karşılaştırma Operatörleri

    • eq(Equal)
      Ülkesi ‘USA’ olanları getirir.
      https://localhost:5001/odata/personel?$filter=ulke eq 'USA'
    • ne(Not Equal)
      Ülkesi ‘USA’ olmayanları getirir.
      https://localhost:5001/odata/personel?$filter=ulke ne 'USA'
    • gt(Greater Than)
      PersonelId değeri 5’ten büyük olanları getirir.
      https://localhost:5001/odata/personel?$filter=personelid gt 5
    • ge(Greater Equal)
      PersonelId değeri 5 ve 5’ten büyük olanları getirir.
      https://localhost:5001/odata/personel?$filter=personelid ge 5
    • lt(Less Than)
      PersonelId değeri 5’ten küçük olanları getirir.
      https://localhost:5001/odata/personel?$filter=personelid lt 5
    • le(Less Equal)
      PersonelId değeri 5’ten küçük ve 5’e eşit olanları getirir.
      https://localhost:5001/odata/personel?$filter=personelid le 5

    Mantıksal Operatörler

    • and
      Ülkesi ‘USA’ ve bölgesi ‘WA’ olan personelleri getirir.
      https://localhost:5001/odata/personel?$filter=ulke eq 'USA' and bolge eq 'WA'
    • or
      Ülkesi ‘USA’ veya bölgesi ‘WA’ olan personelleri getirir.
      https://localhost:5001/odata/personel?$filter=ulke eq 'USA' or bolge eq 'WA'

    Aritmatik Operatörler

    • add(Addition)
      Maaşa 500 eklendiğinde 1500’e eşit olan personelleri getir.
      https://localhost:5001/odata/personel?$filter=maas add 500 eq 1500
    • sub(Subtraction)
      Maaşından 500 çıkarıldığında 1500’e eşit olan personelleri getir.
      https://localhost:5001/odata/personel?$filter=maas sub 500 eq 1500
    • mul(Multiplication)
      Maaşı 1.5 ile çarpıldığında 1500’e eşit olan personelleri getir.
      https://localhost:5001/odata/personel?$filter=maas mul 500 eq 1500
    • div(Division)
      Maaşı 3’e bölündüğünde 1500’e eşit olan personelleri getir.
      https://localhost:5001/odata/personel?$filter=maas div 500 eq 1500

    Fonksiyonel Operatörler

    • endswith
      Adı ‘y’ ile bitenleri getirir.
      https://localhost:5001/odata/personel?$filter=endswith(Adi, 'y')
    • startswith
      Adı ‘y’ ile başlayanları getirir.
      https://localhost:5001/odata/personel?$filter=startswith(Adi, 'y')
    • length
      Adının karakter sayısı 2’den fazla olanları getirir.
      https://localhost:5001/odata/personel?$filter=length(Adi) gt 2
    • indexof
      Adı ‘r’ harfi ile başlayan personelleri getirir.
      https://localhost:5001/odata/personel?$filter=indexof(Adi, 'N') eq 0
    • trim
      Boşlukları temizlenmiş ad değeri ‘Nancy’e eşit olanları getirir.
      https://localhost:5001/odata/personel?$filter=trim(Adi) eq 'Nancy'
    • year
      1992’de doğanları getirir.
      https://localhost:5001/odata/personel?$filter=year(DogumTarihi) eq 1992
    • month
      5. ayda doğanları getirir.
      https://localhost:5001/odata/personel?$filter=month(DogumTarihi) eq 5
    • day
      9. günde doğanları getirir.
      https://localhost:5001/odata/personel?$filter=day(DogumTarihi) eq 9

    Diğer tüm $filter operatörlerini görmek için buradaki dökümanı inceleyebilirsiniz.

  • $select
    Bir entityden dönecek olan propertylerin belirlenmesini sağlar.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.Select();
                });
    

    Örnek olarak aşağıdaki isteği ve çıktısını inceleyiniz;
    https://localhost:5001/odata/personel?$select=adi, soyadi

    Böylece client ile server arasında transfer edilen data boyutu ve miktarı törpülenerek performanslı bir transfer söz konusu olacaktır.

     
     
     
     
     

  • $orderby
    Data üzerinde sıralama yapılmasını sağlar.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.Select().OrderBy();
                });
    

    $orderby; küçükten büyüğe ‘asc’ ve büyükten küçüğe ‘desc’ olmak üzere iki türlü sıralama gerçekleştirmektedir. Bunun için aşağıdaki örnekleri inceleyebilirsiniz;

    • asc
      Büyükten küçüğe sıralar.
      https://localhost:5001/odata/personel?$select=adi, soyadi&$orderby=adi asc
    • desc
      Küçükten büyüğe sıralar.
      https://localhost:5001/odata/personel?$select=adi, soyadi&$orderby=adi desc
  • $count
    Gelen data miktarının adedini verir.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.Filter().Count();
                });
    

    Örnek olarak aşağıdaki sorguları inceleyiniz;
    Toplam kayıt miktarını getirir.
    https://localhost:5001/odata/personel?$count=true

    Şarta uygun kayıt miktarını getirir.
    https://localhost:5001/odata/personel?$filter=year(IseBaslamaTarihi) eq 1992&$count=true

  • $top
    İlk n adet veriyi getirir.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.OrderBy().Select().MaxTop(50); //Maximum girilebilecek Top değerini belirtiyoruz.
                });
    

    PersonelId değerine göre büyükten küçüğe sıralanmış listeden ilk 3 verinin adını ve soyadını getirir.
    https://localhost:5001/odata/personel?$select=adi, soyadi&$top=3&$orderby=personelid desc
    Asp.NET Core WEB API - OData Query Options

  • $skip
    n adet veriyi atlar.

    Bu seçeneği kullanabilmek için endpoint üzerinden herhangi bir metot eklemeye gerek yoktur. İlgili operatif özellik dahili olarak gelecektir.

    PersonelId değerine göre sıralanmış personellerden 3 ve 4. personelleri getirir.
    https://localhost:5001/odata/personel?$select=adi, soyadi&$skip=2&$top=2

  • $expand
    Sorgulama yapılan entityde bulunan ve fiziksel olarak ilişkiye sahip olan navigation propertylerin sorgulanmasını ve böylece ilişkisel verilerin elde edilmesini sağlar.

    Bu seçeneği kullanabilmek için endpoint üzerinden aşağıdaki gibi tanımlanması gerekmektedir.

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapODataRoute("odata", "odata", builder.GetEdmModel());
                    endpoints.Count().Expand();
                });
    

    Aşağıdaki örnekleri inceleyiniz;

    • Personel entitysi içerisindeki ‘Satislar’ propertysi expand edilmekte ve ilişkisel olarak personellerin yaptığı tüm satışlar getirtilmektedir.
      https://localhost:5001/odata/personel?$expand=satislar

      Asp.NET Core WEB API - OData Query Options

    • Personellerin yaptığı tüm satışlarla birlikte sadece ‘SevkAdi’ ve ‘MusteriId’si getirtilmektedir.
      https://localhost:5001/odata/personel?$select=adi, soyadi&$expand=satislar($select=SevkAdi, MusteriId)

      Asp.NET Core WEB API - OData Query Options

    • Personellerden ilkinin tüm satışları getirtilmektedir.
      https://localhost:5001/odata/personel(1)?$select=adi, soyadi&$expand=satislar ($select=SevkAdi, MusteriId)&$count=true
      Asp.NET Core WEB API - OData Query Options
    • Personellerin yaptığı satışların miktarını getirir.
      https://localhost:5001/odata/personel?$select=adi&$expand=satislar($count=true;$select=satisid)

Endpoint Seviyesinde Operatör Belirleme

Yukarıdaki operatörleri incelerseniz eğer her biri için ‘Startup.cs’ dosyasındaki ‘Configure’ metodunda ayrı ayrı tanımlama yapmamız gerekti. Halbuki endpoint seviyesinde de hangi operatörülerin kullanılabileceğini aşağıdaki gibi belirtebilmekteyiz.
Asp.NET Core WEB API - OData Query Options
Görüldüğü üzere ‘EnableQuery’ attribute’unda ‘Allowed…’ ile başlayan tüm propertyler esasında bu actionda aktif olacak operatörleri belirlememizi sağlamaktadırlar.

Örneğin aşağıdaki kod bloğunu incelerseniz eğer;

        [EnableQuery(AllowedFunctions = AllowedFunctions.All)]
        public IActionResult Get()
        {
            return Ok(_northwindContext.Kategoriler.ToList());
        }

‘Get’ fonksiyonunda tüm fonksiyonel operatörlerin çalışmasına endpoint seviyesinde izin verildiğini göreceksiniz.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*