ساخت کوئری با استفاده از زبان Linq در سی شارپ

LINQ مخفف Language Integrated Query می باشد که به وسیله آن می توان اطلاعات را از منابع مختلف استخراج نمود. در برنامه نویسی پایگاه داده (مانند SQL Server) با استفاده از دستورات T-SQL می توان اطلاعات را استخراج نمود و LINQ تقریبا مشابه دستور SELECT پایگاه داده می باشد با این تفاوت که مانند دستورات T-SQL محدود به استراج اطلاعات از جداول پایگاه داده نمی باشد بلکه از آن می توان برای کار با هر نوع اطلاعات استفاده نمود.

نحوه استفاده

یکی از بزرگترین مزایای LINQ، انجام عملیات بر روی هر نوع داده ای می باشد که ساختاری مانند Collection دارد و این امکان باعث شده بسیاری از برنامه نویسان سی شارپ به جای انجام عملیات در پایگاه داده SQL Server، کلیه عملیات مربوط به استخراج اطلاعات را توسط LINQ انجام دهند.

فرض کنید کلاسی به نام Product و با مشخصات زیر ایجاد شده است:

class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public int Price { get; set; }
}

و همانند مثال توضیح داده شده در مقاله قبلی لیستی از Product ها به شکل زیر ایجاد و مقدار دهی شده اند.

static void Main(string[] args)
{
    List<Product> products = new List<Product>();
    products.Add(new Product { ProductId = 101, ProductName = "Galaxy S10", Price = 890 });
    products.Add(new Product { ProductId = 102, ProductName = "iPhone 8", Price = 910 });
    products.Add(new Product { ProductId = 102, ProductName = "iPhone X", Price = 1050 });
    products.Add(new Product { ProductId = 102, ProductName = "Note 10", Price = 949 });
    products.Add(new Product { ProductId = 102, ProductName = "HUAWEI P40 Pro", Price = 899 });
    Console.ReadLine();
}

در این مثال متغیر products یک کالکشن (مجموعه) می باشد و به عبارتی دیگر این کلاس، لیستی از Productها می باشد و به وسیله دستورات LINQ می توانید به روش های مختلفی اطلاعات را استخراج و یا فیلتر نمایید. اگر قصد داشته باشید اطلاعات یک محصول را در پایگاه داده SQL Server استخراج نمایید دستورات آن به شکل زیر خواهد بود.

SELECT * FROM Product

و معادل این دستور در LINQ به شکل زیر است:

var data = (from p in products
            select p).ToList();

در این مثال data متغیری می باشد که نتیجه Query در آن ذخیره می گردد. P متغیری می باشد که به فیلدهای درون مجموعه products اشاره می کند و products نیز همان مجموعه اطلاعاتی می باشد. در انتهای دستورات LINQ می توان از متدهای .FirstOrDefault() و یا .ToList() استفاده نمود. اگر Query ایجاد شده بیش از یک عنصر را بر می گرداند می بایست از ToList و اگر قرار است فقط یک عنصر را برگرداند می توانید از FirstOrDefault استفاده نمایید.

معمولا متغیری که قرار است نتیجه Query در آن ذخیره گردد از نوع var تعریف می شود تا نوع آن متناسب با نوع اطلاعات استخراج شده باشد. اگر قصد داشته باشید نوع اطلاعات را صریحاً مشخص نمایید می توانید به شکل های زیر نیز آن را تعریف نمایید.

List<Product> data = (from p in products
            select p).ToList();
Product data = (from p in products
            select p).FirstOrDefault();

در مثال اول لیستی از Prdouct ها استخراج شده اما در مثال دوم تنها یک Product استخراج می شود.

اعمال شرط

یکی از مهمترین اهداف در ساخت برنامه های مختلف (تحت ویندوز، وب و ...) استخراج اطلاعات به روش های مختلف می باشد. برای مثال اگر قصد داشته باشید اطلاعات محصولی را بر اساس Id آن استخراج کنید دستورات SQL و LINQ آن به شکل زیر خواهد بود:

SQL

SELECT * FROM Product 
WHERE ProductId=101
LINQ

var data = (from p in products
            where p.ProductId==101
            select p).FirstOrDefault();

اگر قصد داشته باشید از عملگرهای منطقی مانند AND و OR استفاده کنید دستورات به شکل زیر خواهند بود.

Using OR in SQL 

SELECT * FROM Product
WHERE ProductId = 101 OR ProductId=102
Using OR in LINQ

var data = (from p in products
            where p.ProductId==101 || p.ProductId==102
            select p).ToList();
Using AND in SQL 

SELECT * FROM Product
WHERE ProductId > 101 AND ProductId < 105
Using AND in LINQ

var data = (from p in products
            where p.ProductId > 101 && p.ProductId < 105
            select p).ToList();

استخراج فیلدهای دلخواه

اگر قصد داشته باشید برخی از فیلدهای یک جدول (مجموعه) را استخراج کنید می توانید به شکل زیر عمل کنید.

SQL

SELECT ProductId, ProductName FROM Product
LINQ

var data = (from p in products
            select new
            {
                p.ProductId,
                p.ProductName
            }).ToList();

مرتب سازی اطلاعات

اطلاعات را هنگام استخراج به دو شکل صعودی و نزوی می توانید مرتب نمایید.

SQL

SELECT ProductId, ProductName FROM Product
Orderby ProductName asc
SELECT ProductId, ProductName FROM Product
Orderby ProductName desc
LINQ

var data = (from p in products
            orderby p.ProductName ascending
            select p).ToList();
var data = (from p in products
            orderby p.ProductName descending
            select p).ToList();

JOIN

یکی از پر کاربردترین دستورات برای کار با اطلاعات، استفاده از JOIN می باشد که جهت ادغام اطلاعات دو یا چند جدول (کالکشن) مورد استفاده قرار می گیرد. استفاده از JOIN در LINQ با تنوع بیشتری نسبت به دستورات SQL قابل پیاده سازی می باشد و در بسیاری موارد حتی بدون استفاده از JOIN نیز می توان اطلاعات را استخراج نمود. بطور کلی نحوه استفاده از JOIN به شکل زیر می باشد.

SQL

SELECT * FROM Product 
INNER JOIN Category ON Product.CategoryId = Category.CategoryId
LINQ

var data = (from p in products
            join c in categories on p.CategoryId equals c.CategoryId
            select p).ToList();

در این مثال در بخش دستورات LINQ با آنکه اطلاعات دو جدول JOIN شده اما فقط اطلاعات جدول Product برگردانده می شود زیرا در مقابل select فقط متغیر p استفاده است. در صورتیکه قصد داشته باشید اطلاعاتی هم از product و هم از category استخراج شود می توانید فیلدها را به تفکیک تعیین نمایید.

var data = (from p in products
            join c in categories on p.CategoryId equals c.CategoryId
            select new
            {
                p.ProductId,
                c.CategoryName,
                p.ProductName,
                p.Price
            }).ToList();

معمولا LINQ همراه با Entity Framework استفاده می شود که وظیفه اصلی آن مدل سازی جداول پایگاه داده و تبدیل آنها به کلاس های برنامه نویسی می باشد. هنگام مدل سازی جداول پایگاه داده و روابط بین آنها، روابطی نیز بین کلاس ها از طریق ارث بری برقرار می شود که همین امر استخراج اطلاعات از جداولی که با یکدیگر در ارتباط هستند را تسهیل می بخشد. برای مثال اگر فرض کنیم اطلاعات دو کلاس Product و Category با استفاده از Entity Framework از پایگاه داده استخراج شده اند می توان به وسیله دستورات زیر اطلاعات دلخواه را از آنها استخراج نمود.

var data = (from p in products
            select new
            {
                p.ProductId,
                p.Category.CategoryName,
                p.ProductName,
                p.Price
            }).ToList();

این روش هنگامی کاربرد دارد که ارتباط 1 به N بین جداول برقرار باشد و شما قصد استخراج اطلاعات از جدول سمت N (در این مثال product) را دارید.