C#Yazılım

C# ve SQL İle JOIN Kullanımı

C# serisinin bu bölümünde sql veritabanı sorgularında kullanılan join ifadelerinden bahsedeceğim. Seriyle birlikte geliştirmek olduğum “Araç Kiralama Sistemi” Projesi içerisinde EntityFramework’ün JOIN özelliğini kullandım. Proje veritabanında yer alan farklı tablolardaki bilgileri kullanarak tek bir sorgu içerisinde farklı bilgilere ilişkisel olarak nasıl erişebildiğimizi göreceğiz.

Proje içerisinde yer alan kiralık araçlara ait bilgiler Cars tablosunda, marka isim ve ID eşleşmeleri Brands tablosunda ve renklerin ID eşleşmelerini Colors tablosunda tutuluyor. Bir arabaya ait bilgileri Cars tablosundan çektiğimiz zaman brand-marka kısmı sadece ID değeri olarak getiriliyor. Aynı şekilde arabaların renk ile ilgili sütununda ilgili rengin yalnızca ID değeri yer alıyor. Bunun sebebi daha sonradan yapılabilecek renk ve marka isimlerindeki değişikliklerde kolaylık sağlamak ve code refactoring işlemini kolaylaştırmaktır. Yani projemiz tamamlandıktan 1-2 yıl vs. sonra bir araba markasının isminde bir güncellemeye gidilebilir veya araba markalarının sonuna yada başına bir ek getirilmesi istenebilir. (Mutlaka ama mutlaka değişiklik yapılacaktır !) Bu durumda her araba için eğer Cars tablosunda renk sütununda string olarak renkleri kaydetmiş olsaydık gidip tek tek bu renkleri düzenlememiz gerekecekti.

Araç Kiralama Sistemi projesinde bu problemin önüne geçilmesi adına güzel sistematik bir mimari oluşturdum. Cars tablosunda marka ve renk sütunları için yalnızca ID değerleri yer almaktadır. Bu şekilde zaman içerisinde istediğimiz gibi rahatça güncellemeler yapabileeceğiz.

Şimdi gelelim bu bölümün konusu olan Inner Join ifadelerine…

Yukarıda anlattığım veritabanı yapısında Cars tablosundan veri çekerken marka ve renk bilgilerinin yalnızca ID değerlerine erişebiliyorduk. Fakat bir arayüzde Müşteri veya satış personeli için bu ID değerleri hiç bir şey ifade etmeyecektir. Yani ID değerlerinin karşılığı olan renkler ve marka bilgileri oto kiralama sisteminin arayüzünde açıkça gösterilmelidir. Bu durumda yapacağımız işlem ilişkisel veritabanları mantığıyla Cars tablosundaki herhangi bir aracın rengini Colors tablosundan ID değerleriyle eşleştirerek ve marka bilgisini Brands tablosundaki ID değerleriyle eşleştirerek göstermektedir. Evet burada ilişki ID değerleri ile sağlanmaktadır.

Let me put it this way

Kullanıcı arayüzden bir araç seçtiği zaman aracın rengi Cars tablosunda yer alan ID değerine göre Colors tablosundan, aracın marka bilgisi Cars Tablosunun BrandId sütünunda yer alan ID değerine göre Brands tablosundan çekilerek bilgiler birleştirilir ve kullanıcıya sunulur.

Bunun için öncelikle projemizin Entities katmanında bir klasör oluşturarak adını DTOs olarak tanımlıyorum. Daha sonra bu klasör içerisine araç detayları hakkında bir birleştirme işlemi yapacağım için CarDetailDto.cs adında bir class oluşturuyorum ve mutlaka public class olarak tanımlıyorum. Burada yeni bir nesne gibi araç detaylarında yer almasını istediğim tüm özellikleri tek tek tanımlıyorum.

CarDetailDto.cs Dosyası:

using System;
using System.Collections.Generic;
using System.Text;
using Core;

namespace Entities.DTOs
{
    public class CarDetailDto:IDto
    {
        public int Id { get; set; }
        public int ColorId { get; set; }
        public int BrandId { get; set; }
        public string CarName { get; set; }
        public string BrandName { get; set; }
        public string ColorName { get; set; }
        public decimal DailyPrice { get; set; }
        public int ModelYear { get; set; }
        public string Description { get; set; }
    }
}

Daha sonra projemin DataAccess katmanında yer alan Concrete (Somut sınıfların yer aldığı klasör) klasörü altında EntityFramework klasörü içerisindeki EfCarDal.cs dosyası içerisine hangi bilgilerin veritabanındaki hangi tablodan çekielceği ve neye göre JOIN edileceğini kodlamaya başlıyorum.

EfCarDal.cs Dosyası

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Core.DataAccess.EntityFramework;
using DataAccess.Abstract;
using Entities.Concrete;
using Entities.DTOs;
using Microsoft.EntityFrameworkCore;

namespace DataAccess.Concrete.EntityFramework
{
    public class EfCarDal : EfEntityRepositoryBase<Car, MydbContext>, ICarDal
    {
        public List<CarDetailDto> GetProductDetails()
        {            

            using (MydbContext context = new MydbContext())
            {
                var result = from ca in context.Cars
                             join br in context.Brands
                             on ca.BrandId equals br.BrandId
                             join co in context.Colors
                             on ca.ColorId equals co.ColorId
                             select new CarDetailDto
                             {
                                 BrandId = br.BrandId,
                                 BrandName = br.BrandName,
                                 ColorId = co.ColorId,
                                 ColorName = co.ColorName,
                                 Id = ca.Id,
                                 CarName = ca.carName,
                                 Description = ca.Description,
                                 ModelYear = ca.ModelYear,
                                 DailyPrice = ca.DailyPrice
                             };
                return result.ToList();

            }

        }
    }
}

Evet C# içersinde JOIN ifademizi yukarıdaki kod parçasında olduğu gibi yazabiliriz. Burada görüldüğü gibi result değişkenine sorgumuzun sonucunu atadıktan sonra LINQ kütüphanesinin yadımıyla ToList() metodunu kullanarak bir array’a dönüştürüp return ediyoruz.

Yukarıda 2 Join ifadesi bir arada kullanılmıştır. Farklı projerlerde yada farklı ihtiyaçlar doğrultusunda daha fazla join ifadesi eklenebilir. Burada hangi bilginin hangi tablodan alınacağı ve tablolar arasından hangi bilgiye göre birleşletirme-ilişkilendirme-join yapılacağı açıkca belirtilmektedir. Projenin kodlarına GitHub üzerinden erişebilir ve detaylıca inceleyebilirsiniz.

Araç Kiralama Sistemi projesinde şuan aktif olarak iki farklı detaylandırma dosyası yer almaktadır. Bunlardan bir tanesi yukarıda araç detayları için kullanılan, diğeri ise kiralama bilgisinin detayları için kullanılan EfRentalDal.cs dosyası içerisndeki join ifadesidir. Bu dosyada 3 adet Join kullanılarak Rentals, Cars, Customers ve Users tabloları Join edilmiştir. Burada yazılan join ifadesinin yalnızca ilgili kısmını aşağıya ekliyorum. Dosyanın tamamını github üzerinden inceleyebilirsiniz. Burada ilgili kısmı vermekteki maksadım kod karmaşının gözünüzü korkutmaması ve doğrudan JOIN işini yapan kodları görmenizdir.

EfRentalDal.cs

using (MydbContext context = new MydbContext())
            {
                var result = from re in context.Rentals
                             join ca in context.Cars
                             on re.CarId equals ca.Id
                             join cus in context.Customers
                             on re.CustomerId equals cus.Id
                             join us in context.Users
                             on cus.UserId equals us.Id
                             select new RentalDetailDto
                             {
                                 Id = re.Id,
                                 CarName = ca.carName,
                                 CarId = ca.Id,
                                 RentDate = re.RentDate,                                 
                                 UserName = us.FirstName + " " + us.LastName 

                             };
                return result.ToList();    

Yukarıdaki kodlar geliştirmekte olduğum “Araç Kiralama Sistemi” ne ait kodlardır. Bunların yanısıra farklı birer örnek olması adına aşağıda bir e-ticaret sisteminde yer alabilecek join ve where ifadelerini içeren kodların ekran görüntülerini sizin için paylaşıyorum. Bu kodlar bir eticaret sistemindeki ürünlerin listelenmesi veya belirli niteliklere-filtrelere göre listelenmesini sağlayan kodlar olarak gerçek hayattan gerçek örneklerdir..

Join ifadelerinin kullanımına yönelik projemden kesitlerle olabildiğince sizlere aktarmaya ve kendimce not çıkarmaya çalıştım. Eklemek istediğiniz veya sormak istediğiniz noktalarda yorum yazmaktan ve mail atmaktan çekinmeyin.

Bilgi paylaştıkça çoğalır mottosuyla bu bölümü tamamlıyorum ve bol bilgili günler diliyorum..

Not: Projenin kaynak kodlarına Github adresimden erişebilirsiniz. Yıldız vermeyi ve takip etmeyi ihmal etmeyin !

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir