Real Estate – AspNet Core 8.0 – Bölüm 9

aspnet core 8 - real estate murat yücedağ
aspnet core 8 - real estate murat yücedağ
Paylaş

Bu Yazıyı Paylaş

veya linki kopyala

AspNet Core 8.0 ile geliştirdiğimiz Real Estate projesinin bu bölümünde geçtiğimiz derslerde Category için yaptığımız tüm işleri Product için yapacağız. Ancak burada farklı olan şey Product tablosunun diğer tablolarla ilişkilendirilmiş olması. Gelin birlikte buna bakalım. Unutmadan Murat Yücedağ hocamızın videosunun linkine buradan ulaşabilirsiniz. Bir önceki yazıyı okumadıysanız;

thumbnail
Bir Önceki Yazı
Real Estate – AspNet Core 8.0 Eğitimine Başladım – Bölüm 1-8

Product İşlemleri – AspNet Core 8.0 – Real Estate Projesi

Projenin anlatımına geçmeden önce kaynakları belirtelim. AspNet projemizin GitHub linki için buraya tıklayın.

İlk olarak datayı alacağımız metodu oluşturabilmek için, Repository, klasör tanımlamalarını gerçekleştiriyoruz. Bunun için Repositories klasörünün içinde ProductRepository adında Repository, IProductRepository adında da interface tanımlaması gerçekleştiriyoruz.

Product Dtos

IPorductRepository’i oluşturduğumuzda ilgili Task’lerin tanımlanması sırasında Product için DTO oluşturmadığımızı fark ediyoruz ve DTO’ları oluşturmak için Dtos klasöründe PorductDtos adında bir klasör tanımlıyoruz.

ResultProductDto’nun oluşturulması ile devam ediyoruz. Admin tarafında çalıştığımız için bazı sütunlara ihtiyaç duymadık. ResultProductDto’da tanımladığımız prop’lar şunlar;

	public int ProductID { get; set; }
	public string Title { get; set; }
	public decimal Price { get; set; }
	public string City { get; set; }
	public string District { get; set; }
        public int ProductCategory { get; set; }

ProductCategory’i veri çekerken Category tablosu ile ilişki kurmak için kullanacağız.

ProductRepository

Repositories altında ProductRepository klasörüne ProductRepository’i de oluşturuyoruz. Ardından ProductRepository’nin IProductRepository’den kalıtım almasını sağlıyoruz.

using System;
namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
	public class ProductRepository: IProductRepository
	{
		
	}
}

Bunun için “: IProductRepository” eklememiz yeterli. Henüz IProductRepository içerisinde kodlarımız olmadığı için bize implemente et uyarısı vermiyor. IProductRepository içerisinde metodlarımızı tanımladığımızda ProductRepository içerisinde bize uyarı verecektir.

İlk metodumuzu IProductRepository interface’ine tanımlayalım. Bu metodun adı GetAllProductAsync olsun. Adından da anlayabileceğiniz üzere tüm product’ları bize getirecek. Dolayısıyla biz Task<List<>> kullanmalıyız. Dönüş tipi olarakta ResultProductDto kullanmalıyız. Yani IProductRepository’miz şu şekilde oldu;

using System;
using RealEstate_Dapper_Api.Dtos.ProductDtos;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
	public interface IProductRepository
	{
		Task<List<ResultProductDto>> GetAllProductAsync();
	}
}

İlk metodumuzu tanımladığımıza göre ProductRepository bize kızacaktır. Çünkü IProductRepository interface’indeki metodu implemente etmedik. Gelin bunu da hemen yapalım

Önerilen Yazı:  Real Estate Projesi ASPNET CORE 8.0 bölüm 21

ProductRepository metod implementasyonu

ProductRepository içerisine girdiğimizde üst tarafta kalıtım ile tanımladığımız IProductRepository interface’inin altının çizili olduğunu göreceğiz. Üzerine gelip “Implement Interface” butonuna basarak bu metodu implemente edebiliriz.

aspnet core 8.0 - implement interface

Ardından kodumuz şu şekilde olacaktır;

using System;
using RealEstate_Dapper_Api.Dtos.ProductDtos;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
    public class ProductRepository : IProductRepository
    {
        public Task<List<ResultProductDto>> GetAllProductAsync()
        {
            throw new NotImplementedException();
        }
    }
}

Elbette veritabanı ile iletişim kurabilmemiz için bir context’e ihtiyacımız var. Bunun için metodlardan önce şu kodu eklemeliyim.

        private readonly Context _context;

        public ProductRepository(Context context)
        {
            _context = context;
        }

Bu kod sayesinde artık _context diyerek ORM araçları yardımı ile database’e ulaşabileceğim. Kodumuza bunu eklediğimizde şu şekilde gözükecek.

using System;
using RealEstate_Dapper_Api.Dtos.ProductDtos;
using RealEstate_Dapper_Api.Models.DapperContext;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
    public class ProductRepository : IProductRepository
    {

        private readonly Context _context;

        public ProductRepository(Context context)
        {
            _context = context;
        }


        public Task<List<ResultProductDto>> GetAllProductAsync()
        {
            throw new NotImplementedException();
        }
    }
}

Şimdi query yazarak ve context sınıfını kullanarak veri döndürme vakti;

using Dapper;
using RealEstate_Dapper_Api.Dtos.ProductDtos;
using RealEstate_Dapper_Api.Models.DapperContext;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
    public class ProductRepository : IProductRepository
    {

        private readonly Context _context;

        public ProductRepository(Context context)
        {
            _context = context;
        }


        public async Task<List<ResultProductDto>> GetAllProductAsync()
        {
            string query = "Select * From Product";

            using (var connection = _context.CreateConnection())
            {
                var values = await connection.QueryAsync<ResultProductDto>(query);
                return values.ToList();
            }
        }
    }
}

Burada dikkat etmemiz gereken bir kaç nokta var. Metod async olmalı. Metodun veri dönüş tipi “ResultProductDto” olmalı. Query’de “Product” tablosuna istek attığımızdan emin olmalıyız. Ayrıca connection.QueryAsync kısmında da dönecek verinin “ResultProductDto” olduğundan emin olmalıyız. Artık controller tarafını oluşturabiliriz.

Products Controller – ASP.NET Core 8.0

Controllers klasörü altında ProductsController dosyasını oluşturduk.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;


namespace RealEstate_Dapper_Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {


    }
}

Varsayılan olarak bu şekilde gözüküyor. Şimdi ise productrepository sınıfından bir nesne alarak controller için güvenli şekilde (dolaylı yoldan) dataya bağlanabiliriz. Bu işlemi yaptığımızda kodumuz şöyle olmalı.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using RealEstate_Dapper_Api.Repositories.ProductRepository;

namespace RealEstate_Dapper_Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly IProductRepository _productRepository;

        public ProductsController(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }


    }
}

Dataya bağlanmak için repository’mizi de çağırdığımıza göre artık ilk endpoint’imizi oluşturabiliriz.

Önerilen Yazı:  Real Estate Projesi ASPNET CORE 8.0 bölüm 14

Bunun için ProductList adında bir metod tanımlayalım.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using RealEstate_Dapper_Api.Repositories.ProductRepository;

namespace RealEstate_Dapper_Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly IProductRepository _productRepository;

        public ProductsController(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }

        [HttpGet]
        public async Task<IActionResult> ProductList()
        {
            var values = await _productRepository.GetAllProductAsync();
            return Ok(values);
        }
    }
}

ProductList EndPoint’imizi de oluşturduğumuza göre yapmamız gereken son bir şey kalıyor. Program.cs dosyasında eklemeler.

Program.cs tarafında tanımlama

builder.Services.AddTransient<IProductRepository, ProductRepository>();

Tanımlayacağımız kod yukarıdaki kod. Bu kod sayesinde IProductRepository’i Controller’da çağırdığımızda program ProductRepository’den bir örnek üretmesi gerektiğini anlıyor ve ProductRepository’nin ilgili metodlarını içe aktarır.

AddTransient<IProductRepository, ProductRepository>(): Bu satır, IProductRepository arayüzünün ProductRepository sınıfına nasıl eşleştirileceğini belirtir ve bu eşleştirmeyi hizmet koleksiyonuna ekler. AddTransient metodu, her talep edildiğinde yeni bir örnek oluşturan geçici (transient) bir hizmet kaydı oluşturur.Yani, bir bileşen (örneğin bir controller) IProductRepository‘i talep ettiğinde, ASP.NET Core bu arayüzü uygulayan ProductRepository sınıfından yeni bir örnek oluşturur ve bu örneği ilgili bileşene enjekte eder. Her talep edildiğinde farklı bir örnek oluşturulması, bağımlılıkların izole edilmesine ve beklenmeyen davranışlardan kaçınılmasına yardımcı olur.Bu yapı sayesinde, ProductRepository sınıfı IProductRepository arayüzüne bağımlı bir şekilde kullanılabilir ve gelecekte bu bağımlılığı değiştirmek veya farklı bir uygulama parçasına enjekte etmek daha kolay hale gelir. Bu da kodun daha modüler ve test edilebilir olmasını sağlar.

Artık uygulamamız hazır. Uygulamamızı ayağa kaldırıp deneyebiliriz.

Uygulamayı başlat ve Api’yi çalıştır

Toolbar’da yer alan sol üstteki play butonu ile uygulamayı ayağa kaldırıyoruz.

Play butonunun hemen yanındaki ayarlara dikkat edin. RealEstate_Dapper_Api – http > Debug mode ve Google Chrome seçili.

Products altındaki GET metodu olan /api/Products kısmını genişletiyoruz ve ardından “Try it out” butonuna basıp Execute diyoruz. Ardından aşağıdaki kısımda bize 200 dönüyor ve yanında ise api den dönen liste.

Önerilen Yazı:  Real Estate – AspNet Core 8.0 – Bölüm 10

İlişkili veriler ile birlikte getirelim

Bunun için ilk olarak bir DTO tanımlayalım. Bu DTO’nun adı ResultProductWithCategoryDto olsun.

Bu sefer Repository’mizin prop’ları şu şekilde olacak;

using System;
namespace RealEstate_Dapper_Api.Dtos.ProductDtos
{
	public class ResultProductWithCategoryDto
	{
        public int ProductID { get; set; }
        public string Title { get; set; }
        public decimal Price { get; set; }
        public string City { get; set; }
        public string District { get; set; }
        public string CategoryName { get; set; }

    }
}

Bu tanımlamadan sonra IProductRepository’e gidip Task’imizi tanımlayabiliriz.

IProductRepository’de GetAllProductWithCategory

using System;
using RealEstate_Dapper_Api.Dtos.ProductDtos;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
	public interface IProductRepository
	{
		Task<List<ResultProductDto>> GetAllProductAsync();
		Task<List<ResultProductWithCategoryDto>> GetAllProductWithCategory();
	}
}

Bu sefer DTO olarak “ResultProductWithCategoryDto” kullanacağız. Çünkü dönecek veri Category’i de içinde barındıracak.

Yeni metodu implement edelim

ProductRepository üzerinde yeni metodu “implement interface” yardımı ile implement ediyoruz. Kodumuz şu şekilde gözükecek.

using Dapper;
using RealEstate_Dapper_Api.Dtos.ProductDtos;
using RealEstate_Dapper_Api.Models.DapperContext;

namespace RealEstate_Dapper_Api.Repositories.ProductRepository
{
    public class ProductRepository : IProductRepository
    {

        private readonly Context _context;

        public ProductRepository(Context context)
        {
            _context = context;
        }


        public async Task<List<ResultProductDto>> GetAllProductAsync()
        {
            string query = "Select * From Product";

            using (var connection = _context.CreateConnection())
            {
                var values = await connection.QueryAsync<ResultProductDto>(query);
                return values.ToList();
            }
        }

        public Task<List<ResultProductWithCategoryDto>> GetAllProductWithCategory()
        {
            throw new NotImplementedException();
        }
    }
}

Ardından ilgili metodumuzu şu şekilde güncelliyoruz;


        public async Task<List<ResultProductWithCategoryDto>> GetAllProductWithCategory()
        {
            string query = "Select ProductID,Title,Price,City,District,CategoryName From Product inner join Category on Product.ProductCategory = Category.CategoryID";

            using (var connection = _context.CreateConnection())
            {
                var values = await connection.QueryAsync<ResultProductWithCategoryDto>(query);
                return values.ToList();
            }
        }

Şimdi kalan tek işlem EndPoint’i Controller tarafında oluşturmak.

ProductsController’a gidiyoruz.


        [HttpGet("ProductListWithCategory")]
        public async Task<IActionResult> ProductListWithCategory()
        {
            var values = await _productRepository.GetAllProductWithCategory();
            return Ok(values);
        }

Kodumuzu ekliyoruz. Artık yapmamız gereken test. Evet projemizi ayağa kaldırıp testini yaptığımızda sonuç aşağıdaki gibi başarılı.

0
mutlu
Mutlu
0
_zg_n
Üzgün
0
sinirli
Sinirli
0
_a_rm_
Şaşırmış
0
k_t_
Kötü
0
beynim_yand_
Beynim Yandı
0
_eytani
Şeytani
Real Estate – AspNet Core 8.0 – Bölüm 9

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

Giriş Yap

Eyüp Furkan Tüylü ayrıcalıklarından yararlanmak için hemen giriş yapın veya hesap oluşturun, üstelik tamamen ücretsiz!