Dapper - Multi Mapping

Bu yazımda Dapper ORM'inde ilişkili tablolardan veri çekme işlemini örneklerle anlatacağım. Bu işlemi Query metodumuzun multi mapping özelliği sayesinde yapabiliriz.

Önceki konulardaki örneklerimde yararlandığım Northwind veritabanınında karşılık gelen modelleri oluşturduk.

Veritabanımızdaki Order, OrderDetails, Categories ve Products tablolarına karşılık gelen Siparis,SiparisDetay, Kategori ve Urunler sınıfları aşağıdaki gibidir. Bu sınıfları kullanarak veri çekme işlemlerini yapabileceğiz.

public class Kategori
    {
        public string CategoryName { get; set; }

        public int CategoryId { get; set; }

        public string Description { get; set; }

        public Urunler Urun { get; set; }
    }

    public class Siparis
    {
        public int OrderID { get; set; }

        public string ProductName { get; set; }

        public Urunler Products { get; set; }

        public DateTime OrderDate { get; set; }

        public DateTime ShippedDate { get; set; }

        public DateTime RequiredDate { get; set; }

        public SiparisDetay OrderDetails { get; set; }
    }

    public class SiparisDetay
    {
        public string ProductName { get; set; }

        public Urunler Products { get; set; }

        public int OrderID { get; set; }

        public int Quantity { get; set; }

        public double UnitPrice { get; set; }

        public double Discount { get; set; }
    }

    public class Urunler
    {
        public int ProductId { get; set; }

        public string ProductName { get; set; }

        public int UnitsInStock { get; set; }

        public double UnitPrice { get; set; }

        public int CategoryId { get; set; }

        public string CategoryName { get; set; }

        public Kategori Kategori { get; set; }

        public SiparisDetay OrderDetails { get; set; }
    }

Bağlantımızı oluşturduğumuz  DbConnect class'ımız

public class DbConnect
    {
        private DbConnect()
        {

        }

        private static SqlConnection _connection;

        public static SqlConnection Connection
        {
            get
            {
                if (_connection==null)
                {
                    var connectionString = ConfigurationManager.ConnectionStrings["northWind"].ConnectionString;
                    _connection = new SqlConnection(connectionString);
                }

                if (_connection.State!=ConnectionState.Open)
                {
                    _connection.Open();
                }

                return _connection;
            }

        }

AppConfig veya web.config'de Connection String'imizi tanımladık

  <connectionStrings>
    <add name="northWind" connectionString="Server=ServerName;Database=NORTHWND;Trusted_Connection=True;"/>
  </connectionStrings>


Product ve Category tablosundaki ortak alana göre veri çekme işlemini yapıyoruz. Bu işlemle ürünün adını ve kategori adını görebiliriz. Urunler türünden bir List döndürecek metodumuzu oluşturuyoruz.


public static List<Urunler> ProductCategory()
{
    var connection = DbConnect.Connection;

    var query = "SELECT * FROM dbo.Categories INNER JOIN  dbo.Products ON dbo.Categories.CategoryID = dbo.Products.CategoryID";

    var list = connection.Query<Urunler, Kategori, Urunler>(query, (urun, kat) =>
    {
         urun.Kategori = kat;
         return urun;
    }, splitOn: "CategoryID").ToList();

    return list;
} 

connection değişkeni veritabanımıza bağlanacağımız connection'dır. Açık bir bağlantıya ihtiyaç duyar.

query değişkeninde joinli sorgumuz var bu şekilde ilişkili tablolardaki verileri çekebiliriz.

Query metodunda <Urunler, Kategori, Urunler> yazılması demek ilişkili tablolara ait modeller ve dönecek listenin tipini belirtmiş olduk. Urunler tipinden bir liste dönecektir ve bu listede kategori bilgisi de olacaktır. Veritabanında Categori ve Product tablosu birbirleriyle ilişkili tablolardır. İki tablonun ilişki şekline bakacak olursak;

"Bir ürünün bir kategorisi vardır. Bir kategori birden çok ürüne ait olabilir."

(query, (urun, kat) => { urun.Kategori = kat; return urun; }, splitOn: "CategoryID")

Bu metodun ilk parametresi sql sorgu cümlesidir, ikinci parametresi ise (urun,kat) sırasıyla Urunler ve Kategori türünden bir nesne alan ve her bir satırı Urunler ve Kategori nesnesi barındıracak bir fonksiyon oluşturuyoruz. Bu örneğimizde urun nesnesine kat nesnesi eklenir. Böylece her iki tablodaki bilgileri de göreceğiz.son parametresi de her iki tabloda join yapılacak ortak alanı belirten splitOn parametresidir. Bu örnekte CategoryID her iki tabloda da ortaktır.

Kullanmak istersek aşağıdaki gibi kullanabiliriz.

var urunler = DapperMethods.ProductCategory(); 

foreach (var item in urunler)
{
    Console.WriteLine(item.ProductName+" "+item.CategoryName);
}

Urunler'de CategoryName alanı oluşturduk ve mapping işlemi yaparken urun.Kategori = kat; yazarak iki tabloyu Dapper metoduyla birbirine bağladık. Urunler modeline Kategori türünden Kategori property'si tanımlamıştık bu şekilde verileri çekme işlemi yapabildik.



Yorumlar