LinqToExcel Kullanımı - Excel ve CSV Verilerini LINQ İle Sorgulama

20.5.2018 Hikmet Okumuş 114 2 NuGet Package

Merhaba arkadaşlar,

Sizlere Excel üzerinden LINQ ile veri okuyabilmemizi sağlayan LinqToExcel paketini örneklerle açıklamaya çalışacağım. Kurulum için NuGet Package Manager üzerinden paketi indirebilirsiniz.


www.hikmetokumus.com


Örnek excel için Northwind veritabanında yer alan Products tablosundaki verileri kullanmaktayım. Excel içeriği aşağıdaki gibidir.

www.hikmetokumus.com


The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.' Eğer bu hatayı alıyorsanız bilgisayarınıza Access Database Engine kurulumunu yapmanız gerekmektedir. Kurulum için aşağıdaki adresi ziyaret edebilirsiniz.

Access Database Engine


Çalışma Sayfasındaki Verileri Sorgulama

İlk örneğimizde excel üzerinden yapılacak sorgulamaya göre sonuçlar Product sınıfına aktarılacaktır. Eğer Worksheet için bir isim belirtilmezse, varsayılan olarak Sheet1 değerine göre sorgulama yapacaktır. Bu şekilde çalıştırdığımızda bir hata ile karşılacağız.

using System;
using System.IO;
using System.Linq;

namespace LinqToExcel.Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
            var excel = new ExcelQueryFactory(filePath);
            
            var products = from c in excel.Worksheet< Product>()
                           select c;

            foreach (var product in products)
            {
                Console.WriteLine($"{product.ProductID} - {product.ProductName}");
            }

            Console.ReadLine();
        }
    }

    public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public int? SupplierID { get; set; }
        public int? CategoryID { get; set; }
        public string QuantityPerUnit { get; set; }
        public decimal? UnitPrice { get; set; }
        public short? UnitsInStock { get; set; }
        public short? UnitsOnOrder { get; set; }
        public short? ReorderLevel { get; set; }
        public bool Discontinued { get; set; }
        public int? Sample { get; set; }
        public bool? IsTrue { get; set; }
    }
}

www.hikmetokumus.com


Yukarıda söylediğim gibi, eğer çalışma sayfasının adını belirtmezsek, varsayılan olarak Sheet1 isimli bir sayfayı bulmaya çalışacaktır. Türkçe sürüm kullandığım için Sayfa1 isimli çalışma sayfasını dikkate almayacaktır. Worksheet parametresi olarak Safya1 değerini yazabiliriz, ama biz data ile uyumlu olması için Excel sayfa adını Products olarak değiştirelim ve uygulamadan worksheetName parametresini girerek çağıralım.

www.hikmetokumus.com

	static void Main(string[] args)
	{
	    string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");	
	    var excel = new ExcelQueryFactory(filePath);
	    
	    var products = from c in excel.Worksheet< Product>("Products")
	                   select c;
	
	    foreach (var product in products)
	    {
	        Console.WriteLine($"{product.ProductID} - {product.ProductName}");
	    }
	
	    Console.ReadLine();
	}

www.hikmetokumus.com

www.hikmetokumus.com


Property İsimlerini Excel Kolon İsimleri İle Eşleştirmek

Excelde yer alan kolon isimleri, sizin sınıfınızda bulunan property isimleri ile uyum sağlamayabilir. Bu gibi bir durumda ExcelQueryFactory içerisinde yer alan AddMapping metodunu kullanarak eşleştirme yapabiliriz. İki kullanım şeklide aşağıdaki gibidir.

    class Program
    {
        static void Main(string[] args)
        {
            string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
            
            var excel = new ExcelQueryFactory(filePath);
            excel.AddMapping< Product>(x => x.ID, "ProductID");
            //excel.AddMapping("ID", "ProductID");

            var products = from c in excel.Worksheet< Product>("Products")
                           select c;

            foreach (var product in products)
            {
                Console.WriteLine($"{product.ID} - {product.ProductName}");
            }

            Console.ReadLine();
        }
    }

    public class Product
    {
        public int ID { get; set; }
        public string ProductName { get; set; }
        public int? SupplierID { get; set; }
        public int? CategoryID { get; set; }
        public string QuantityPerUnit { get; set; }
        public decimal? UnitPrice { get; set; }
        public short? UnitsInStock { get; set; }
        public short? UnitsOnOrder { get; set; }
        public short? ReorderLevel { get; set; }
        public bool Discontinued { get; set; }
        public int? Sample { get; set; }
        public bool? IsTrue { get; set; }
    }

Aynı işlemi AddMapping metodunu kullanmak yerine Property için Attribute kullanarakta yapabiliriz. ExcelColumn Attribute ü AddMapping ile aynı amaca hizmet etmektedir.

    public class Product
    {
        [ExcelColumn("ProductID")]
        public int ID { get; set; }
    }

LinqToExcel.Row Sınıfının Kullanımı

Worksheet metodu generic bir argument almaktadır. Eğer bir tip parametresi verilmezse, sonuçlar Row sınıfına set edilecektir. DataRow ile benzer şekilde çalışmaktadır. Erişmek istenilen kolon için kolon ismi ya da kolon index i kullanılabilir.

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);
        
        var products = from c in excel.Worksheet("Products")
                       where c["CategoryID"] == "2" 
                       select c;

        foreach (var product in products)
        {
            Console.WriteLine($"{product["ProductID"]} - {product["ProductName"]}");
        }

        Console.ReadLine();
    }

www.hikmetokumus.com


UnitPrice değeri 10 dan büyük olan kayıtları sorgulamak istediğimde eşitliğin sol tarafı string olduğu için hata alınacaktır. Bu gibi bir durumda Cast metodunu kullanarak tip dönüşümü yapabiliriz.

    var excel = new ExcelQueryFactory(filePath);
    var products = from c in excel.Worksheet("Products")
                   where c["UnitPrice"].Cast< int>() > 10
                   select c;

Başlığı Olmayan Excel Sayfasını Sorgulamak

Bunun için WorksheetNoHeader metodu kullanılmaktadır. Erişmek istenilen kolon için index numarası belirtilmelidir.

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);
        
        var products = from c in excel.WorksheetNoHeader("Products")
                       where c[5].Cast< int>() > 10
                       select c;

        foreach (var product in products)
        {
            Console.WriteLine($"{product[0]} - {product[1]}");
        }

        Console.ReadLine();
    }

Bir Çalışma Sayfasındaki Belirli Bir Aralığı Sorgulamak

Aşağıdaki örnek görseldeki gibi sadece seçili alandaki dataları sorgulamak istediğimizde bu yönteki kullanabiliriz.

www.hikmetokumus.com


    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);

        var products = from c in excel.WorksheetRange< Product>("A1", "F12", "Products")
                       select c;

        foreach (var product in products)
        {
            Console.WriteLine($"{product.ID} - {product.ProductName}");
        }

        Console.ReadLine();
    }

www.hikmetokumus.com


Birde benzer işlemi yapan WorksheetRangeNoHeader metodu bulunmaktadır. Başlığı olmayan exceller için kullanılabilir. Generic bir tip parametresi almaz, sonuçları RowNoHeader modeli ile geri döner.

var products = from c in excel.WorksheetRangeNoHeader("A1", "F12", "Products")
               select c;

Index Numarasına Göre Çalışma Sayfasını Sorgulamak

Excel içerisine 2 tane yeni sayfa ekledim. Sayfa görüntüleri aşağıdaki gibidir. Customer modelinin içeriğini worksheetIndex belirterek dolduralım. Bunun için Worksheet metodunu kullanacağız. Dikkat edilmesi gereken kısım, index sayfaların mevcuttaki dizilimine göre çalışmamaktadır. Öncelikle sayfa isimlerini alfabetik olarak sıralamakta, sıralama sonucuna göre verilen indexe karşılık gelen sayfanın datasını doldurmaktadır.

www.hikmetokumus.com

www.hikmetokumus.com

    class Program
    {
        static void Main(string[] args)
        {
            string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
            var excel = new ExcelQueryFactory(filePath);

            var customers = from c in excel.Worksheet< Customer>(0)
                            select c;            
        }
    }
    
    public class Customer
    {
        [ExcelColumn("CustomerID")]
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }    

Index numarası 0 olan yani "ABC Customers" sayfasındaki datalar yüklenecektir. 1 dediğimizde "Customers" sayfasına ait datalar gelecektir. Index numarasını 2 olarak verdiğimizde, Generic olarak belirtilen tip içerisinde kolon - property ismi eşleşen bir değer varsa o değerleri set edecektir. Sayfadaki tüm kolonlar ile modelin tüm property lerinin eşleşmesi gibi bir zorunluluk yoktur.


Dönüşüm Kontrolleri

Customer sayfasına örnekteki gibi IsActive kolonunu ekledim. Bu kolon içerisinde; Y = true, N = false değerini ifade etmektedir. Normal yapıda bu datayı modele basmak için string ya da char tipinde bir property kullanarak öncelikle datayı doldurur, sonrasında kontrol yapıları ile true - false olduğuna karar verebiliriz. Ya da aşağıdaki gibi bir yöntemle bool tipindeki bir alana doğrudan datayı basabiliriz.

www.hikmetokumus.com

    class Program
    {
        static void Main(string[] args)
        {
            string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");

            var excel = new ExcelQueryFactory(filePath);
            excel.AddTransformation< Customer>(x => x.IsActive, value => value == "Y");

            var customers = from c in excel.Worksheet< Customer>("Customers")
                            select c;

            Console.ReadLine();
        }
    }
    
    public class Customer
    {
        [ExcelColumn("CustomerID")]
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool IsActive { get; set; }
    }    

www.hikmetokumus.com


Çalışma Sayfa İsimlerini Sorgulamak

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);

        var worksheetNames = excel.GetWorksheetNames();
    }

www.hikmetokumus.com


Çalışma Sayfasına Ait Kolon İsimlerini Sorgulamak

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);

        var columnNames = excel.GetColumnNames("Products");
    }

www.hikmetokumus.com


Boşlukları Temizlemek

Excelde verilerin başında ya da sonunda boşluklar olabilir. Modele datayı set ettikten sonra bu durumu kontrol edebiliriz. Ya da TrimSpacesType ile bu kuralı en başında uygulatabiliriz.

www.hikmetokumus.com

www.hikmetokumus.com

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.xlsx");
        var excel = new ExcelQueryFactory(filePath);
        excel.TrimSpaces = Query.TrimSpacesType.Both;

        var customers = from c in excel.Worksheet< Customer>("Customers")
                        select c;
    }

www.hikmetokumus.com


CSV Dosyasını Okumak

Ekstra yapmamız gereken birşey yok, sadece dosya yolunu vermemiz yeterlidir.

    static void Main(string[] args)
    {
        string filePath = Path.Combine(Environment.CurrentDirectory, "Data.csv");
        var excel = new ExcelQueryFactory(filePath);

        var customers = from c in excel.Worksheet< Customer>()
                        select c;
    }

www.hikmetokumus.com

www.hikmetokumus.com


Kütüphane açık kaynak ve Github üzerinde yayınlanmaktadır. Repository linkine aşağıdan ulaşabilirsiniz. Başarılı bir kütüphane olmuş ve ciddi anlamda bizlere kolaylık sağlamaktadır. Dilerim sizlerede faydalı olur.

LinqToExcel


Başarılar dilerim.

Merhaba arkadaşlar

Bilgisayarımda kurulu MySQL 5.7 versiyonunu 8.0 versiyonuna yükselttikten sonra, Workbench ve benzeri programlarla veritabanına bağlanmak istediğimde "ERROR 1251: Client does not support authentication protocol requested by server; consider upgrading MySQL client" şeklinde bir hata almaya başladım. Benzer hatayı sizde alırsanız aşağıdaki sorguyu Command Line Client üzerinde çalıştırdığınızda sorun giderilecektir.

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'

www.hikmetokumus.com

MySQL Sistem Kullanıcılarını Listelemek

3.12.2017 Hikmet Okumuş 471 0 MySQL

Merhaba arkadaşlar,

MySQL' de sistem kullanıcılarını aşağıdaki tablodan sorgulayabilirsiniz.
SELECT * FROM mysql.user;

SELECT CONCAT(QUOTE(user),'@',QUOTE(host)) UserAccount FROM mysql.user;

Başarılar dilerim.

MySQL Database Boyutunu Öğrenmek

11.11.2017 Hikmet Okumuş 498 0 MySQL

Merhaba arkadaşlar,

MySQL database boyutunu öğrenmek için aşağıdaki SQL sorgusunu kullanabilirsiniz. Bu sorgu size toplam kapasiteyi megabyte olarak verecektir.
SELECT  SUM(ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 ), 2)) AS "SIZE IN MB"
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = "SCHEMA-NAME";

Gigabyte olarak öğrenmek için;

SELECT  SUM(ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 /1024 ), 2))  AS "SIZE IN GB"
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = "SCHEMA-NAME";

Başarılar dilerim.

Merhaba arkadaşlar,

Stopwatch, genel itibari ile bir prosesin başlangıçtan bitişe kadar geçen işlem süresini ölçmek için kullanılmaktadır. Farklı yöntemlere göre işlem süresi baz alınarak kod optimizasyonu yapmamızı ve farklı yöntemleri performans yönünden benchmark etmemize yardımcı olur. Nesneye ait özelliklere ulaşmak için aşağıdaki MSDN linkine bakabilirsiniz.

Stopwatch

Örneğimizde iki farklı yöntemi benchmark yapacağız. Elimizde bir sayı koleksiyonu var ve biz bu koleksiyonun elemanlarını bir Console uygulaması ile ekrana yazdırmak istiyoruz. Koleksiyon elemanlarını yazdırmak için bir döngü işlemine ihtiyacımız var. Öncelikle bir For döngüsü ile ekrana yazdırmayı deneyelim.

    static void Main(string[] args)
    {
        List< int> numbers = new List< int>();
        for (int i = 1; i <= 1000; i++)
            numbers.Add(i);

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        for (int i = 0; i < numbers.Count; i++)
        {
            Console.WriteLine(numbers[i]);
            Thread.Sleep(10);
        }        

        stopwatch.Stop();            
        Console.WriteLine($"Time elapsed (For): {stopwatch.Elapsed}");

        Console.ReadLine();
    }

www.hikmetokumus.com

For döngüsü ile işlem başlangıç bitiş süresini hesapladık. Kodu farklı yöntemler ile optimize etsek daha performanslı bir sonuç elde edebilir miyiz ? Bunu görmek için Parallel.For yapısına göre kodumuzu revize edelim ve Stopwatch ile süreyi hesaplayalım.

    static void Main(string[] args)
    {
        List< int> numbers = new List< int>();
        for (int i = 1; i <= 1000; i++)
            numbers.Add(i);

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        Parallel.ForEach< int>(numbers, x =>
        {
            Console.WriteLine(x);
            Thread.Sleep(10);
        });

        stopwatch.Stop();
        Console.WriteLine($"Time elapsed (Parallel For): {stopwatch.Elapsed}");        

        Console.ReadLine();
    }

www.hikmetokumus.com

Her iki yapıya göre işlem sürelerini baz aldığımızda, Parallel.For yapısının daha iyi bir performans sunduğu görülmektedir. Artık kodumuzu Parallel.For yapısına göre değiştirebiliriz. Konunun başında belirttiğim gibi, Stopwatch sayesinde farklı işlem yapılarını, kod bloklarını bu şekilde süre bazında ölçebilir, yapıları benchmark edebiliriz.


Başarılar dilerim.

Merhaba arkadaşlar,

Bir veri kümesinde, where kısıtı ile sonuca dahil etmek istediğimiz ya da dışında tutmak istediğimiz koleksiyon türünde kriterimiz olabilir. SQL de bunu In ya da Exists kullanarak yapabilmekteyiz. Linq karşılığı olarak böyle bir işlem yapmak istediğimizde Contains ya da Any metodları tercih edilebilir. Bir örnek üzerinden detaylandıralım.

Contains İle In Sorgusu Oluşturmak

    static void Main(string[] args)
    {
        using (var context = new NorthwindContext())
        {
            int[] idCollection = { 1, 3, 4, 7 };

            List< Categories> categories = (from x in context.Categories
                                           where idCollection.Contains(x.CategoryID)
                                           select x)
                                           .ToList();

            foreach (var item in categories)
                Console.WriteLine(item.CategoryName);         
        }

        Console.ReadLine();
    }

Örneğimize göre idCollection içerisine, sonuca dahil etmek istediğimiz kategorilerin id değerlerini yazdık. Sonrasında Linq ile sorgularken, idCollection dizisi içerisindeki değer ile eşleşen kayıtları getirmek için Contains metoduna CategoryID bilgisini argüment olarak yazdık. Linq sorgusu çalıştığı zaman bize aşağıdaki gibi bir sonuç döndürecektir.

www.hikmetokumus.com

Biz sorgumuzu içeren olarak yazdık. Eğer tam tersi bir durumda, koleksiyon içerisindeki değerleri içermeyen yani "NOT IN" olarak yazmak için şu şekilde revize etmemiz yeterli olacaktır.

List< Categories> categories = (from x in context.Categories
                               where idCollection.Contains(x.CategoryID) == false
                               select x)
                               .ToList();

www.hikmetokumus.com

Örneği Linq kullanarak yazdık. Lambda ifadesi ile aşağıdaki gibi yazılabilir.

List< Categories> categories = context.Categories.Where(x => idCollection.Contains(x.CategoryID)).ToList();

"NOT IN" için

List< Categories> categories = context.Categories.Where(x => !idCollection.Contains(x.CategoryID)).ToList();

Any İle In Sorgusu Oluşturmak

Daha önce Any kullanımı ile ilgili bir makale yazmıştım. Aşağıdaki linkten ilgili makaleye erişebilirsiniz.

Linq İle Any Metodu Kullanımı

Any metodunu kullanarak Contains ile yaptığımız işlemdeki aynı sonucunu elde edebiliriz.

static void Main(string[] args)
{
    using (var context = new NorthwindContext())
    {
        int[] idCollection = { 1, 3, 4, 7 };

        List< Categories> categories = (from x in context.Categories
                                       where idCollection.Any(f => f == x.CategoryID)
                                       select x)
                                      .ToList();

        foreach (var item in categories)
            Console.WriteLine(item.CategoryName);
    }

    Console.ReadLine();
}

www.hikmetokumus.com

İçermeyen kısıtı için aşağıdaki gibi düzeltme yapılabilir.

List< Categories> categories = (from x in context.Categories
                               where idCollection.Any(f => f == x.CategoryID) == false
                               select x)
                              .ToList();

www.hikmetokumus.com

Her iki yöntem ile de aynı sonucu elde edebiliyoruz. Fakat Entity Framework' ün oluşturduğu sorgular, iki yöntem için de farklılık göstermektedir. Kullanım tercihinizi buna göre yapabilir, aynı zamanda SQL Management - Execution Plan ile performans ve güç tüketimlerini karşılaştırabilirsiniz.

Contains

SELECT 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[CategoryName] AS [CategoryName], 
    [Extent1].[Description] AS [Description], 
    [Extent1].[Picture] AS [Picture]
    FROM [dbo].[Categories] AS [Extent1]
    WHERE [Extent1].[CategoryID] IN (1, 3, 4, 7)

Any

SELECT 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[CategoryName] AS [CategoryName], 
    [Extent1].[Description] AS [Description], 
    [Extent1].[Picture] AS [Picture]
    FROM [dbo].[Categories] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM  (SELECT 
            1 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            3 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]
        UNION ALL
            SELECT 
            4 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]
        UNION ALL
            SELECT 
            7 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable4]) AS [UnionAll3]
        WHERE [UnionAll3].[C1] = [Extent1].[CategoryID]
    )

Başarılar dilerim.

Linq İle Except Kullanımı

23.6.2017 Hikmet Okumuş 790 0 Linq & Lambda

Merhaba arkadaşlar,

Except, bir koleksiyon içerisinde bulunan elemanları, argüman olarak gönderilen başka bir koleksiyondaki elemanlar ile karşılaştırır ve aynı olan kayıtları birinci koleksiyondan çıkarmak için kullanılmaktadır. Bu işlem sonucunda geriye birinci koleksiyonun yeni halini döndürmektedir.

Örnek olarak aşağıdaki gibi 2 tane sayı dizimiz olsun. Except metodu ile numberA içerisinde geçen numberB elemanları dışlanacak ve geriye yeni bir koleksiyon döndürelecektir.

    static void Main(string[] args)
    {
        int[] numberA = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int[] numberB = { 1, 3, 5, 7, 9 };

        var result = numberA.Except(numberB);

        foreach (var item in result)
            Console.WriteLine(item);

        Console.ReadLine();
    }

www.hikmetokumus.com

Alternatif olarak bu işlemi bir döngü yöntemi ile de yapabilirdik. Fakat Expect bu gibi bir işlemde daha basit bir kullanım imkanı sunmaktadır.


Başarılar dilerim.

Linq İle Inner Join Kullanımı

21.6.2017 Hikmet Okumuş 1293 0 Linq & Lambda

Merhaba arkadaşlar,

Join, iki ya da daha fazla sonuç kümesini, bir ya da birden fazla kritere göre birbirine bağlayan ve geriye bir sonuç kümesi döndüren bir yapıdır. SQL Server' da olduğu gibi LINQ to SQL' de bize JOIN yazmamıza imkan vermektedir. Şimdi LINQ ile nasıl iki veri kümesini birleştireceğiz bunu örnek üzerinde inceleyelim.

Örneğimizde Northwind veritabanı kullanılacaktır. Veritabanı içerisinde bulunan Products ve Categories tabloları için bir INNER JOIN sorgusu oluşturacağız. LINQ öncesinde bu işlemi SQL sorgusu ile yapmak isteseydik, aşağıdaki gibi bir sorgu oluşturmamız gerekecekti.

SELECT P.ProductName, C.CategoryName 
FROM dbo.Products P
INNER JOIN dbo.Categories C ON P.CategoryID = C.CategoryID

www.hikmetokumus.com

Şimdi benzer örneği LINQ ile yazalım ve iki tabloyu INNER JOIN ile birleştirelim.

using (var context = new NorthwindContext())
{
    var result = from p in context.Products
                 join c in context.Categories on p.CategoryID equals c.CategoryID
                 select new
                 {
                     ProductName = p.ProductName,
                     CategoryName = c.CategoryName
                 };

    result.ToList().ForEach(x =>
    {
        Console.WriteLine($"Product Name: {x.ProductName}, Category Name: {x.CategoryName}");
    });
}

www.hikmetokumus.com

İlk örneğimizde, sonucu doğrudan SQL sorgusu yazarak görmüştük. Şimdi LINQ ile yazdığımız kodun, bizim için arka tarafta oluşturmuş olduğu SQL sorgusuna bakalım.

SELECT 
[Extent2].[CategoryID] AS [CategoryID], 
[Extent1].[ProductName] AS [ProductName], 
[Extent2].[CategoryName] AS [CategoryName]
FROM  [dbo].[Products] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]

LINQ tarafından oluşturulan sql sorgusuna baktığımız zaman, ilk örnekte yazılan sorgu ile benzer bir sql ifadesinin oluştuğu görülmektedir. JOIN ifadesinde kullanılan equals anahtarı, eşitliği karşılaştırmak için kullanılmıştır. equals yerine "==" şeklinde bir eşitlik kontrolü kullanamayız. LINQ, JOIN işlemi için bu şekilde bir syntax' ı desteklememektedir. Eğer işlemimiz gereği equals yerine not equals şeklinde bir sorgulama yapılacaksa, bu tarz bir syntax' ı da LINQ desteklememektedir. Eşit değil gibi bir kontrol için farklı yöntemler kullanılabilmektedir.


Başarılar dilerim.

C# İle Sealed Anahtar Kelimesinin Kullanımı

7.6.2017 Hikmet Okumuş 956 0 C#

Merhaba arkadaşlar,

Kalıtım, bir nesne üyelerinin farklı nesne / nesnelere aktarılmasına ve üyelerin bu nesneler tarafından kullanılmasına yarayan OOP nin en önemli özelliklerinden birisidir. Sealed kullanımı öncesinde kalıtım konusunun tam anlamı ile oturmuş olması gerekmektedir. Sealed, sınıfların kalıtım işlemini engellemek için kullanılan bir anahtar kelimedir. Sealed anahtar kelimesi bir sınıf için uygulanacak ise kalıtımı, bir üye için uygulanacak ise üyenin override edilmesini engellemektedir. Kısaca örnekler üzerinden inceleyelim.

Sınıf İçin Kullanımı

X sınıfı Y sınıfına miras olarak atanmaktadır.

    class X
    {
      
    }

    class Y : X
    {
                                        
    }

X sınıfı için kalıtımı engelleyelim. Bunun için class ifadesinin başına Sealed anahtarını ekliyoruz.

    sealed class X
    {
       
    }

    class Y : X
    {

    }

Bu işlem sonrasında derleme zamanında aşağıdaki gibi bir hata ile karşılaşırız. Bu hata bize X sınıfının herhangi bir nesneye kalıtım ile aktarılamayacağını söylemektedir.

www.hikmetokumus.com

Sınıf Üyeleri İçin Kullanımı

Sealed anahtar kelimesi eğer bir override metod için kullanılırsa, ilgili sınıf başka bir sınıfa kalıtım ile aktarıldığı zaman metodun override edilmesini engellemiş olur. Örnek sınıfımıza bir metod ekleyelim.

    class X
    {
        protected virtual void Test()
        {
            Console.WriteLine("X.Test");
        }
    }

    class Y : X
    {
    
    }

Override etmek istediğimizde Test metodu listede karşımıza çıkmaktadır.

www.hikmetokumus.com

    class X
    {
        protected virtual void Test()
        {
            Console.WriteLine("X.Test");
        }
    }

    class Y : X
    {
        protected override void Test()
        {
            Console.WriteLine("Y.Test");
        }
    }

Şimdi Y sınıfı içerisindeki Test metoduna sealed anahtarını ekleyelim.

    class X
    {
        protected virtual void Test()
        {
            Console.WriteLine("X.Test");
        }
    }

    class Y : X
    {
        protected sealed override void Test()
        {
            Console.WriteLine("Y.Test");
        }
    }

    class Z : Y
    {
    
    }

Yeni eklediğimiz Z sınıfı Y sınıfından kalıtım almaktadır. Şimdi Z sınıfı için override edilecek üyeleri inceleyelim.

www.hikmetokumus.com

Görüldüğü gibi override edilebilecek üyeler arasında Test metodu yer almamaktadır. Z sınıfından Test metoduna erişim için, Z sınıfının bir kopyası üzerinden ya da sınıf içerisinde base anahtar kelimesi ile miras alınan üyelere erişilebilir ve Y içerisindeki Test metodu bu şekilde kullanılabilir. Ama Y içerisinde Test metodu sealed anahtar kelimesi ile engellendiği için, bu sınıfı miras alan sınıflarda override edilemez.

Y sınıfı içerisinde Test metodu sealed ile engellenmemiş olsun ve Z sınıfından override edelim.

    class X
    {
        protected virtual void Test()
        {
            Console.WriteLine("X.Test");
        }
    }

    class Y : X
    {
        protected override void Test()
        {
            Console.WriteLine("Y.Test");
        }
    }

    class Z : Y
    {
        protected override void Test()
        {
            Console.WriteLine("Z.Test");
        }
    }

Eğer override işleminden sonra Y sınıfında Test metodu için sealed anahtar kelimesini kullanırsak, derleyici tarafından aşağıdaki gibi bir hata ile karşılaşırız.

    class X
    {
        protected virtual void Test()
        {
            Console.WriteLine("X.Test");
        }
    }

    class Y : X
    {
        protected sealed override void Test()
        {
            Console.WriteLine("Y.Test");
        }
    }

    class Z : Y
    {
        protected override void Test()
        {
            Console.WriteLine("Z.Test");
        }
    }

www.hikmetokumus.com

Uygulamalarınızda kalıtımın yapılmasını istemediğiniz sınıflarda güvenliği sağlamak ya da yanlış kalıtım işlemlerini engellemek için sealed anahtarını kullanabilirsiniz.


Başarılar dilerim.

MSSQL Server' da Stored Procedure ve User Defined Function Arasındaki Farklar

6.6.2017 Hikmet Okumuş 1201 0 Microsoft SQL Server

Merhaba arkadaşlar,

MSSQL Server' da Stored Procedure ile User Defined Function arasında bulunan yapısal farklılıklar hakkında aşağıdaki tablodan bilgi alabilirsiniz.
# Stored Procedure User Defined Function
1 Stored Procedure geriye bir değer döndürebilir ya da döndürmeyebilir. Function geriye bir değer döndürmek zorundadır.
2 Stored Procedure SELECT ifadesi ile birlikte; INSERT, UPDATE, DELETE ve benzeri DML ifadelerini kullanabilir. Function sadece SELECT ifadesini kullanmaya izin verir, DML ifadeleri kullanılamaz.
3 Stored Procedure giriş ve çıkış parametrelerine sahip olabilir. Function sadece giriş parametresine sahip olabilir, çıkış parametresi desteklenmemektedir.
4 Stored Procedure içerisinde try catch bloklarının kullanılmasına izin verir. Function try catch bloklarının kullanılmasına izin vermez.
5 Stored Procedure içerisinde Transaction işlemleri yapılabilir. Function içerisinde Transaction işlemine izin verilmez.
6 Stored Procedure içerisinde TABLE değişkeni ve TEMPORARY TABLE kullanılabilir. Function içerisinde TABLE değişkeni kullanılabilir, TEMPORARY TABLE kullanımına izin verilmemektedir.
7 Stored Procedure ile Function çağrılabilir. Function ile Stored Procedure çağrılamaz.
8 Stored Procedure çalıştırmak için EXECUTE/EXEC ifadeleri kullanımaktadır. SELECT/WHERE/HAVING ve benzeri ifadeler ile çağrılamaz. Function çalıştırmak için SELECT ifadesi kullanılmaktadır.
9 Stored Procedure ile döndürülen sonuç kümesi bir JOIN işlemine dahil edilemez. (Procedure içerisinde JOIN kullanımından bahsedilmiyor.) Function ile döndürülen sonuç kümesi JOIN işleminde kullanılabilir. (Function içerisinde JOIN kullanımından bahsedilmiyor.)
10 Stored Procedure içerisinde PRINT ifadesi kullanılabilmektedir. Function içerisinde PRINT ifadesinin kullanımı desteklenmemektedir.

Başarılar dilerim.