۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه ترسیم روابط شی با استفاده از Dapper در ASP.NET Core

از مزیت Dapper برای ایجاد روابط یک به یک، یک به چند و چند به چند در برنامه های ASP.NET Core خود استفاده کنید.

از مزیت Dapper برای ایجاد روابط یک به یک، یک به چند و چند به چند در برنامه های ASP.NET Core خود استفاده کنید.

Dapper یک ORM ساده، سبک و به درستی محبوب (نقشه‌نگار رابطه شی) برای دات نت است. ما اصول کار با Dapper را در مقاله قبلی آموختیم. و در مقاله‌ای قبلی درباره کار با کتابخانه Dapper Extensions بحث کردیم. اخیراً، چند ویژگی های پیشرفته Dapper را بررسی کردیم.

در این مقاله، نحوه کار با نگاشت روابط در Dapper را یاد خواهیم گرفت. به طور خاص، نحوه ترسیم روابط یک به یک، یک به چند و چند به چند را با استفاده از Dapper بررسی خواهیم کرد.

برای استفاده از نمونه کدهای ارائه شده در این مقاله، باید Visual Studio 2022 را در سیستم خود نصب کنید. اگر قبلاً نسخه‌ای ندارید، می‌توانید Visual Studio 2022 را از اینجا بارگیری کنید.

یک پروژه ASP.NET Core Web API در Visual Studio ایجاد کنید

ابتدا، اجازه دهید یک پروژه ASP.NET Core 7 در Visual Studio 2022 ایجاد کنیم. این مراحل را دنبال کنید:

  1. Visual Studio 2022 IDE را راه اندازی کنید.
  2. روی “ایجاد پروژه جدید” کلیک کنید.
  3. در پنجره “ایجاد پروژه جدید”، “ASP.NET Core Web API” را از لیست الگوهای نمایش داده شده انتخاب کنید.
  4. بعدی را کلیک کنید.
  5. در پنجره “پیکربندی پروژه جدید خود”، نام و مکان پروژه جدید را مشخص کنید.
  6. به صورت اختیاری، بسته به تنظیمات برگزیده خود، کادر انتخاب «قرار دادن راه حل و پروژه در یک فهرست راهنمای» را علامت بزنید.
  7. بعدی را کلیک کنید.
  8. در پنجره «اطلاعات اضافی» که در ادامه نشان داده شده است، کادر «استفاده از کنترل‌کننده‌ها (برای استفاده از حداقل API‌ها علامت آن را بردارید» علامت بزنید. ما از حداقل API در این پروژه استفاده نخواهیم کرد. تنظیم «نوع احراز هویت» را روی «هیچ» (پیش‌فرض) بگذارید.
  9. مطمئن شوید که چک باکس‌های «فعال کردن پشتیبانی از API باز»، «پیکربندی برای HTTPS» و «فعال کردن داکر» بدون علامت باقی می‌مانند. ما از این ویژگی‌ها در اینجا استفاده نخواهیم کرد.
  10. روی ایجاد کلیک کنید.

ما از این پروژه ASP.NET Core 7 Web API برای کار با ویژگی‌های پیشرفته Dapper در بخش‌های زیر استفاده خواهیم کرد.

Dapper چیست؟ چرا از آن استفاده کنید؟

نقشه‌نگارهای شی رابطه‌ای برای رسیدگی به «عدم تطابق امپدانس» بین مدل‌های شی در زبان‌های برنامه‌نویسی و مدل‌های داده در پایگاه‌های داده رابطه‌ای استفاده می‌شوند. Dapper یک فریمورک micro-ORM سبک وزن، با کارایی بالا برای .NET و .NET Core است. از طیف گسترده ای از پایگاه های داده مانند Oracle، SQL Server، Oracle، MySQL، PostgreSQL، SQLite و SQL CE پشتیبانی می کند. تیم Stack Overflow Dapper را ایجاد کرد تا یک ORM ساده برای NET باشد. Dapper یک پروژه منبع باز موجود در GitHub است.

چند نقشه در Dapper

Dapper از چند نقشه‌برداری پشتیبانی می‌کند، که به شما امکان می‌دهد یک رکورد را از یک جدول پایگاه داده به چندین رکورد از جدول دیگر نگاشت کنید. با چند نقشه برداری، می توانید داده ها را از چندین جدول پایگاه داده در یک پرس و جو بازیابی کنید.

پیشنهاد جاوا تأخیر GC را کاهش می دهد

برای انجام این کار، هنگام فراخوانی روش Dapper’s Query از پارامتر SplitOn استفاده می کنید. متد SplitOn مشخص می کند که از کدام ستون ها برای تقسیم داده ها به چندین شیء استفاده شود. دو کلاس زیر را در نظر بگیرید.

public class Author {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Book {
    public int Id { get; set; }
    public int AuthorId { get; set; }
    public string Title { get; set; }
    public string ISBN { get; set; }
}

قطعه کد زیر نشان می دهد که چگونه می توانید چند نقشه را با استفاده از Dapper پیاده سازی کنید.

using (var connection = new SqlConnection(connectionString)){
    string query = "SELECT * from Authors A Inner Join Books B ON A.Id = B.AuthorId";
    var authors = connection.Query<Author, Book, Author>(
        query,
        (author, book) =>
        {
            author.Books = author.Books ?? new List<Book>();
            author.Books.Add(book);
        },
    splitOn: "Id"        
    ).Distinct().ToList();
}

نقشه برداری ساده در Dapper

یک جدول پایگاه داده به نام Store را با فیلدهای فهرست شده در جدول زیر در نظر بگیرید.

نام جدول: فروشگاه

نام فیلد

نوع فیلد

Store_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

Store_Name

وارچار

مکان

وارچار

نام جدول: فروشگاه

نام فیلد

نوع فیلد

Store_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

Store_Name

وارچار

مکان

وارچار

پرس و جوی SQL پارامتری شده زیر رکوردی را از جدول پایگاه داده Store که دارای یک Store_Id منطبق است برمی گرداند:  

Select Store_Id, Store_Name, Location
From Store Where Store_Id = @StoreId 

برای بازیابی یک رکورد از جدول پایگاه داده فروشگاه با استفاده از Dapper، از قطعه کد زیر استفاده کنید.

using var connection = new SqlConnection();
var stores = await connection.QueryAsync<Store>(
    sql, new { Store_Id = storeId });

نقشه چندگانه یک به یک رابطه در Dapper

دو جدول پایگاه داده به نام های سفارش و مشتری را با فیلدهای فهرست شده در جداول زیر در نظر بگیرید.

نام جدول: سفارش

نام فیلد

نوع فیلد

Order_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

شناسه_مشتری (کلید_خارجی)

عدد صحیح

تاریخ_سفارش

DateTime

تعداد_سفارش

عدد صحیح

Order_Price

دوبرابر

نام جدول: سفارش

نام فیلد

نوع فیلد

Order_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

شناسه_مشتری (کلید_خارجی)

عدد صحیح

تاریخ_سفارش

DateTime

تعداد_سفارش

عدد صحیح

Order_Price

دوبرابر

نام جدول: مشتری

نام فیلد

نوع فیلد

شناسه_مشتری (کلید_اصلی)

عدد صحیح (تولید خودکار)

First_Name

وارچار

نام_خانوادگی

وارچار

آدرس

وارچار

تلفن

وارچار

ایمیل

وارچار

نام جدول: مشتری

نام فیلد

نوع فیلد

شناسه_مشتری (کلید_اصلی)

عدد صحیح (تولید خودکار)

First_Name

وارچار

نام_خانوادگی

وارچار

آدرس

وارچار

تلفن

وارچار

ایمیل

وارچار

می‌توانید از عبارت SQL زیر برای انتخاب رکورد سفارش و جزئیات مشتری مرتبط با آن استفاده کنید.

Select o.Order_Id, o.Order_Date, c.Customer_Id, c.First_Name, c.Last_Name
From Order o
Inner Join Customer c On o.Customer_Id = c.Customer_Id

کد زیر نشان می دهد که چگونه می توانید یک نگاشت یک به یک بین جداول پایگاه داده سفارش و مشتری ایجاد کنید و سوابق سفارش را با استفاده از Dapper بازیابی کنید.

string query = "Select * From Order o Inner Join Customer c On o.Customer_Id = c.Customer_Id";
var orders = connection.Query<Order, Customer, Order>(query, map:
    (order, customer) =>
    {
      order.Customer = customer;
      return order;
    }, splitOn: "Customer_Id").FirstOrDefault();

نقشه چندگانه رابطه یک به چند در Dapper

اکنون جدول Order را تغییر می‌دهیم تا یک فیلد اضافی اضافه شود. جداول پایگاه داده زیر یک رابطه یک به چند را بین دو موجودیت سفارش و محصول نشان می دهد، به این معنی که می توانید سفارشی داشته باشید که با چندین محصول مرتبط است.

نحوه استفاده از فیلترهای مدیریت مسیر در حداقل APIها در ASP.NET Core 7

نام جدول: سفارش

نام فیلد

نوع فیلد

Order_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

شناسه_محصول (کلید_خارجی)

عدد صحیح

شناسه_مشتری (کلید_خارجی)

عدد صحیح

تاریخ_سفارش

DateTime

تعداد_سفارش

عدد صحیح

Order_Price

دوبرابر

نام جدول: سفارش

نام فیلد

نوع فیلد

Order_ID (کلید_اصلی)

عدد صحیح (تولید خودکار)

شناسه_محصول (کلید_خارجی)

عدد صحیح

شناسه_مشتری (کلید_خارجی)

عدد صحیح

تاریخ_سفارش

DateTime

تعداد_سفارش

عدد صحیح

Order_Price

دوبرابر

نام جدول: محصول

نام فیلد

نوع فیلد

شناسه_محصول (کلید_اصلی)

عدد صحیح (تولید خودکار)

نام_محصول

وارچار

مقدار_محصول

عدد صحیح

قیمت_واحد

دوبرابر

نام جدول: محصول

نام فیلد

نوع فیلد

شناسه_محصول (کلید_اصلی)

عدد صحیح (تولید خودکار)

نام_محصول

وارچار

مقدار_محصول

عدد صحیح

قیمت_واحد

دوبرابر

اکنون می‌توانید از عبارت SQL زیر برای بازیابی همه سفارش‌ها استفاده کنید.

Select Order_Id, Order_Quantity, Order_Date, p.Product_Name
From Order o
Inner Join Product p On o.Product_Id = p.Product_Id

قطعه کد زیر نحوه ایجاد یک نگاشت یک به چند بین جداول سفارش و محصول و بازیابی سوابق سفارش با استفاده از Dapper را نشان می دهد.

string query = "Select * From Order o Inner Join Product p On o.Product_Id = p.Product_Id";
var orders = connection.Query<Order, Product, Order>(query, map:
    (order, product) =>
    {
      order.Product = product;
      return order;
    }, splitOn: "Product_Id;

چند نگاشت روابط چند به چند در Dapper

رابطه چند به چند کمی بیشتر درگیر است. به عنوان مثال، شما می توانید یک رابطه بین واحدهای دانشجو و دوره داشته باشید که در آن یک دانش آموز می تواند در چندین دوره ثبت نام کند در حالی که شما همچنین می توانید یک دوره را با چندین دانش آموز نگاشت کنید. به عبارت دیگر، روابط چند به چند به چندین رکورد در یک جدول اجازه می‌دهد تا با چندین رکورد در جدول دیگر مرتبط شود.

این گونه روابط معمولاً با استفاده از جدول سوم اجرا می شوند که گاهی اوقات “جدول اتصال” یا “جدول پل” نامیده می شود. برای ترسیم یک رابطه چند به چند با استفاده از Dapper، باید جدول join را مدیریت کنید و چندین جستار SQL یا یک جستار به خوبی ساخته شده برای واکشی داده های مرتبط ایجاد کنید.

مایکروسافت از الگوهای فهرست سی شارپ 11، حروف خام رشته ای رونمایی کرد

سه جدول پایگاه داده با نام‌های Student، Course و StudentCourse و فیلدهای مربوط به آنها را همانطور که در جداول زیر نشان داده شده است، در نظر بگیرید.

نام جدول: دانشجو

نام فیلد

نوع فیلد

Student_Id (Primary_Key)

عدد صحیح (تولید خودکار)

First_Name

وارچار

نام_خانوادگی

وارچار

آدرس

وارچار

نام جدول: دانشجو

نام فیلد

نوع فیلد

Student_Id (Primary_Key)

عدد صحیح (تولید خودکار)

First_Name

وارچار

نام_خانوادگی

وارچار

آدرس

وارچار

نام جدول: دوره

نام فیلد

نوع فیلد

شناسه_دوره (کلید_اصلی)

عدد صحیح (تولید خودکار)

عنوان_دوره

وارچار

مدت_دوره

عدد صحیح

تاریخ_شروع

DateTime

نام جدول: دوره

نام فیلد

نوع فیلد

شناسه_دوره (کلید_اصلی)

عدد صحیح (تولید خودکار)

عنوان_دوره

وارچار

مدت_دوره

عدد صحیح

تاریخ_شروع

DateTime

نام جدول: دوره_دانشجو

نام فیلد

نوع فیلد

شناسه_درس_دانشجویی (کلید_اصلی)

عدد صحیح (تولید خودکار)

Student_Id (Foreign_Key)

عدد صحیح

شناسه_دوره (کلید_خارجی)

عدد صحیح

نام جدول: دوره_دانشجو

نام فیلد

نوع فیلد

شناسه_درس_دانشجویی (کلید_اصلی)

عدد صحیح (تولید خودکار)

Student_Id (Foreign_Key)

عدد صحیح

شناسه_دوره (کلید_خارجی)

عدد صحیح

ما می‌توانیم ارتباط بین دانش‌آموزان و دوره‌ها را با استفاده از کلاس‌های زیر نشان دهیم.

public class Student
    {
        public int Student_Id { get; private set; }
        public string FirstName { get; set; } = string.Empty;
        public string LastName { get; set; }
        public string Address { get; set; } = string.Empty;
        public List<Course> Courses { get; set; }
    }
    public class Course
    {
        public int Course_Id { get; private set; }
        public string Course_Title { get; set; }
        public int Course_Duration { get; set; } 
        public DateTime Start_Date { get; set; }
  public List<Student> Courses { get; set; }
    }

به لیست‌های کلاس‌های دانشجو و دوره توجه کنید. در حالی که کلاس Student حاوی لیستی از دوره ها است، کلاس دوره شامل لیستی از دانشجویان است. می توانید از دستور SQL زیر برای بازیابی دانش آموز و داده های مربوط به آن استفاده کنید.

Select s.Student_Id, s.First_Name, s.Last_Name, c.Course_Title
From Student s
Inner Join Student_Course sc ON sc.Student_Id = s.Student_Id
Inner Join Course c ON c.Course_Id = sc.Course_Id

می‌توانید نقشه‌برداری چند به چند بین دانش‌آموز و واحدهای دوره در Dapper ایجاد کنید که به شما امکان می‌دهد سوابق دانش‌آموز را همراه با دوره‌هایی که برای آنها ثبت‌نام کرده‌اند بازیابی کنید. کد اینجاست:

using(var connection = new SqlConnection(connectionString))
{
  string query = "Select s.Student_Id, s.First_Name, s.Last_Name, c.Course_Title From Student s " +
    "Inner Join Student_Course sc ON sc.Student_Id = s.Student_Id " +
    "Inner Join Course c ON c.Course_Id = sc.Course_Id";
  var students = await connection.QueryAsync <Student,
    Course, Student > (query, (student, course) => {
      student.Courses.Add(course);
      return student;
    }, splitOn: "Course_Id");
}

Dapper یک ORM سبک، کارآمد و قابل تنظیم با ویژگی‌های عالی است که می‌تواند قابلیت‌های دسترسی به داده‌ها را در برنامه‌های NET Core شما به میزان قابل توجهی بهبود بخشد. همانطور که دیدیم، Dapper پشتیبانی عالی برای نقشه برداری روابط ارائه می دهد. درباره استفاده از Dapper در مقاله آینده در اینجا چیزهای بیشتری برای گفتن خواهم داشت.