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) را دارید.