در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 6 : عملگرهای استاندارد

در مقالات قبلی در مورد تعدادی از عملگر های LINQ صحبت کردیم، در ادامه به بررسی عملگر های زیر خواهیم پرداخت:

  1. عملگر های Join که برای ادغام دو لیست بر اساس یک یا چندین کلید استفاده می شوند.
  2. عملگر های Grouping که برای گروه بندی لیست بر اساس یک کلید خواص استفاده می شود.
  3. عملگر های Generation که برای تهیه لیستی جدید از مقادیر استفاده می شوند.
  4. عملگر های Equality که برای مقایسه دو لیست استفاده می شوند.
  5. عملگر های Element که برای گرفتن یکی از آیتم های لیست استفاده می شود.

عملگر های Join

افرادی که با کوئری های SQL کار کرده باشند با مفهوم Join آشنایی دارند. عملگر های Join جهت ادغام دو لیست مبتنی بر یک کلید خاص استفاده می شود که شبیه به عملیات inner join در SQL می باشد. برای

مثال، فرض کنیم دو لیست داریم، داخل یکی از لیست ها، مشتریان و داخل لیست دیگر سفارشات مربوط به هر یک از مشتریان را نگهداری می کنیم. حال اگر بخواهیم این دولیست با یکدیگر ادغام شده و هر سفارش به همراه نام سفارش دهنده نمایش داده شود از Join استفاده می کنیم. برای آشنایی بیشتر به یک مثال توجه کنید، فرض کنیم می خواهیم اطلاعات مربوط به سفارشات مشتریان را ذخیره کنیم، برای اینکار دو کلاس با نام های زیر در برنامه تعریف می کنیم:

class Customer
{
    public int CustomerID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Order
{
    public int CustomerID { get; set; }
    public int OrderID { get; set; }
    public string OrderDescription { get; set; }
}

کلاس Customer اطلاعات مشتری را نگهداری کرده و کلاس Order اطلاعات سفارشرا نگهداری می کند، کلاس سفارشات یک خصوصیت با نام CustomerID دارد که برای ارتباط بین مشتری و سفارش استفاده می شود که همان فیلد کلید است (طراحی انجام شده برای این مثال با توجه به اصول شئ گرایی صحیح نمی باشد، اما برای نزدیکی ساختار لیست ها به جداول بانک اطلاعاتی طراحی به این صورت انجام شده است)، در ادامه می خواهیم یک کوئری اجرا کنیم که اطلاعات را به صورت نام مشتری، کد سفارش و توضیحات سفارش برای ما برگرداند، در این قسمت ما می توانیم از عملگر های Join استفاده کنیم:

List customers = new List
{
    new Customer() { CustomerID = 1, FirstName = "Mohammad", LastName = "Sadeghi" },
    new Customer() { CustomerID = 2, FirstName = "Ali", LastName = "Rezaee" }
};

List orders = new List
{
    new Order() { CustomerID = 1, OrderID = 1, OrderDescription = "Order1" },
    new Order() { CustomerID = 1, OrderID = 2, OrderDescription = "Order2" },
    new Order() { CustomerID = 1, OrderID = 3, OrderDescription = "Order3" },
    new Order() { CustomerID = 2, OrderID = 1, OrderDescription = "Order1" },
    new Order() { CustomerID = 2, OrderID = 2, OrderDescription = "Order2" },
};

var joinQuery = from c in customers
                      join j in orders
                      on c.CustomerID equals j.CustomerID into orderDetails
                      from d in orderDetails
                      select new { CustomerName = c.FirstName + " " + c.LastName, OrderID = d.OrderID, OrderDesc = d.OrderDescription };

foreach (var item in joinQuery)
{
    Console.WriteLine(string.Format("Name:{0} OrderID:{1} OrderDesc:{2}", item.CustomerName, item.OrderID, item.OrderDesc));
}

Console.ReadKey();

همانطور که در کد بالا مشاهده می کنید در کوئری از عملگر join برای ادغام سفارشات با اطلاعات مشتری استفاده شده است، ساختاری عملگر های Join به صورت زیر است:

from  in 
join  in  
on  equals 
from r in 
selelct 


در بخش بالا خط سوم تعیین کننده شرط ما برای ادغام دو لیست می باشد که این مقایسه باید بر روی کلید مورد نظر انجام شود. امکان انجام مقایسه بین دو کلید و یا بیشتر نیز وجود دارد، برای مقایسه بین تعداد فیلد های بیشتر باید به صورت زیر عمل کرد:

 from  in 
join  in 
on new {,, ...} equals {,,...}
from r in 
select 

با استفاده از الگوی بالا می توان از چندین فیلد کلید برای نوشتن کوئری استفاده کرد. برای روشن تر شدن یک مثال دیگر را با هم بررسی می کنیم، فرض کنیم داخل کلاس سفارش می خواهیم اطلاعات کالای سفارش داده شده را نیز نگهداری کنیم، برای این منظور کلاسی با نام Product تعریف می کنیم و کلاس Order را به صورت زیر تغییر می دهیم:

class Order
{
    public int CustomerID { get; set; }
    public int OrderID { get; set; }
    public int ProductID { get; set; }
    public string OrderDescription { get; set; }
}

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

همانطور که مشاهده می کنید، در کلاس Order خصوصیتی با نام ProductID تعریف شده که تعیین کننده کد کالای سفارش داده شده می باشد. حالا می خواهیم از لیست سفارشات مشتریان کوئری بنویسیم که نام مشتری، به همراه کد سفارش، نام کالا و قیمت کالا را را نمایش دهد، در این قسمت باید از عملگر join استفاده کنیم که از چندین فیلد برای کلید استفاده می کند:

List customers = new List
{
    new Customer() { CustomerID = 1, FirstName = "Mohammad", LastName = "Sadeghi" },
    new Customer() { CustomerID = 2, FirstName = "Ali", LastName = "Rezaee" }
};

List products = new List
{
    new Product() { ProductID = 1, ProductName = "Product1", Price = 1000 },
    new Product() { ProductID = 2, ProductName = "Product2", Price = 2500 },
    new Product() { ProductID = 3, ProductName = "Product3", Price = 4000 },
    new Product() { ProductID = 4, ProductName = "Product4", Price = 3700 },
};

List orders = new List
{
    new Order() { CustomerID = 1, OrderID = 1, ProductID = 1, OrderDescription = "Order1" },
    new Order() { CustomerID = 1, OrderID = 2, ProductID = 3, OrderDescription = "Order2" },
    new Order() { CustomerID = 1, OrderID = 3, ProductID = 2, OrderDescription = "Order3" },
    new Order() { CustomerID = 2, OrderID = 1, ProductID = 1, OrderDescription = "Order1" },
    new Order() { CustomerID = 2, OrderID = 2, ProductID = 4, OrderDescription = "Order2" },
};

var joinQuery = from c in customers
                      from p in products
                      oin j in orders
                      on new { c.CustomerID, p.ProductID } equals new { j.CustomerID, j.ProductID } into orderDetails
                      from d in orderDetails
                      select new
                      {
                          PersonName = c.FirstName + " " + c.LastName,
                          OrderID = d.OrderID,
                          ProductName = p.ProductName,
                          Price = p.Price,
                          OrderDesc = d.OrderDescription
                      };

همانطور که در کوئری بالا مشاهده می کنید از ترکیب دو کلید CustomerID و ProductID برای انجام عملیات Join استفاده شده که این قابلیت به ما این امکان رو میده تا کوئری های پیچیده ای را بنویسیم. از عملگر های Join در Method Based Query هم می توان استفاده کرد. برای مثال، اولین کوئری نوشته شده در این بخش را می توان به صورت زیر نیز نوشت:

var query = customers.Join(orders, n => n.CustomerID, n => n.CustomerID,
                     (l1, l2) => new
                                   {
                                       PersonName = l1.FirstName + " " + l1.LastName,
                                       OrderID = l2.OrderID,
                                       OrderDesc = l2.OrderDescription
                                    });

نوع دیگری از عملگر Join، استفاده از GroupJoin است، این عملگر برای ادغام یک لیست با مقادیر متناظر در لیست دیگر استفاده می شود، این عملگر برای کار با ساختاری های Hierarchical استفاده می شود. برای آشنایی بیشتر، فرض کنیم لیستی داریم شامل نام کارخانه های خودرو سازی و لیستی دیگر که نام خودرو به همراه شرکت تولید کننده را نگهداری می کند، حال می خواهیم یک کوئری بنویسیم که نتیجه آن نام شرکت و لیستی از خودرو های آن شرکت می باشد، به کد زیر توجه کنید:

List companies = new List()
{
    new Company() { Name = "IranKhodro" },
    new Company() { Name = "Siapa" },
    new Company() { Name = "Hyundai" }
};

List cars = new List()
{
    new Car() { CompanyName = "IranKhodro", Name = "Peikan" },
    new Car() { CompanyName = "IranKhodro", Name = "P 405" },
    new Car() { CompanyName = "IranKhodro", Name = "P Pars" },
    new Car() { CompanyName = "Siapa" , Name = "Pride" },
    new Car() { CompanyName = "Siapa" , Name = "Xantia" },
    new Car() { CompanyName = "Hyundai" , Name = "Azera" },
    new Car() { CompanyName = "Hyundai" , Name = "Sonata" },
    new Car() { CompanyName = "Hyundai" , Name = "Santafeh" },
    new Car() { CompanyName = "Hyundai" , Name = "Genesis" } 
};

var query = companies.GroupJoin(cars, company => company.Name, car => car.CompanyName,
                                    (company, car) => new { company.Name, Cars = car.Select(n => n.Name) });

foreach (var co in query)
{
    Console.WriteLine(co.Name);
    foreach (var car in co.Cars)
        Console.WriteLine(" {0}", car);
}
Console.ReadKey();

class Company
{
    public string Name { get; set; }
}


class Car
{
    public string CompanyName { get; set; }
    public string Name { get; set; }
}

با اجرای کد بالا، خروجی زیر بر روی صفحه Console ظاهر خواهد شد:

IranKhodro
Peikan
P 405
P Pars
Siapa
Pride
Xantia
Hyundai
Azera
Sonata
Santafeh
Genesis

بیشترین کاربرد عملیات های Join در نوشتن کوئری ها بر روی بانک های اطلاعاتی می باشد.

عملگرهای Grouping

عملگر های بعدی که در مورد آن توضیح خواهیم داد عملگر های Grouping یا گروه بندی می باشند، فرض کنیم لیستی از مبلغ های سفارش به همراه تاریخ سفارش را داریم، می خواهیم لیستی را که شامل جمع مبلغ های هر روز می باشد را تهیه کنیم. برای این کار باید نتیجه را بر اساس تاریخ گروه بندی کرده و جمع مبلغ هر روز را حساب کرده و در خروجی نمایش دهیم:

List orderHistory = new List
{
    new OrderHistory() { OrderDate = "1388/01/25", OrderPrice = 125000 },
    new OrderHistory() { OrderDate = "1388/01/25", OrderPrice = 18500 },
    new OrderHistory() { OrderDate = "1388/01/12", OrderPrice = 2500000 },
    new OrderHistory() { OrderDate = "1388/02/12", OrderPrice = 17500 },
    new OrderHistory() { OrderDate = "1388/01/17", OrderPrice = 41000 },
    new OrderHistory() { OrderDate = "1388/01/28", OrderPrice = 250000 },
    new OrderHistory() { OrderDate = "1388/02/06", OrderPrice = 60000 },
    new OrderHistory() { OrderDate = "1388/02/08", OrderPrice = 281000 },
    new OrderHistory() { OrderDate = "1388/03/02", OrderPrice = 236000 },
    new OrderHistory() { OrderDate = "1388/03/02", OrderPrice = 782400 },
};

var query = from e in orderHistory
                 group e by e.OrderDate into dateGrouped
                 orderby dateGrouped.Key
                 select new { Date = dateGrouped.Key, TotalPrice = dateGrouped.Sum(n => n.OrderPrice) };

foreach (var item in query)
{
    Console.WriteLine("{0} {1}", item.Date, item.TotalPrice);
}

Console.ReadKey(); 

با اجرای این دستور خروجی زیر چاپ خواهد شد:

1388/01/12 2500000
1388/01/17 41000
1388/01/25 143500
1388/01/28 250000
1388/02/06 60000
1388/02/08 281000
1388/02/12 17500
1388/03/02 1018400


عملگرهای Generation

از این عملگر ها برای ایجاد مجموعه های جدید از روی مقادیر مجموعه های موجود استفاده می شود. در این بخش به بررسی عملگر های Generation خواهیم پرداخت:

عملگر DefaultIfEmpty

این عملگر در صورتی که مجموعه مورد نظر خالی باشد، یک مجموعه حاوی یک عنصر از نوع اعضای آن مجموعه را بر خواهد گرداند، برای مثال:

List names = new List
{
    "Ali","Mohammad","Mahdi","Abbas","Behzad","Behrooz ","Naser"
};

/* 1 */ Console.WriteLine(names.Where(n => n.StartsWith("D")).First());

/* 2 */ Console.WriteLine(names.Where(n => n.StartsWith("D")).DefaultIfEmpty().First());

با اچرای دستور شماره 1، به دلیل اینکه لیست مورد نظر خالی می باشد، یک Exception ایجاد خواهد شد، زیرا لیست خالی بوده و متد First هیچ عنصری را در لیست نخواهد یافت، ولی با اجرای دستور شماره 2، به دلیل اینکه از متد DefaultIfEmpty استفاده شده است، به دلیل اینکه نتیجه کوئری یک لیست خالی می باشد، یک لیست که تنها دارای یک مقدار و آنهم مقدار پیش فرض نوع string می باشد، بر خواهد گرداند که متد First آن مقدار را بر می گرداند. از این متد در مواقعی که نتیجه کوئری قابل پیش بینی نیست می توان استفاده کرد.

Empty

این متد یک لیست خالی را بر می گرداند. این متد به صورت مستقیم از داخل کلاس Enumerable صدا زده می شود:

IEnumerable result = Enumerable.Empty();

عملگر Range

لیستی حاوی اعداد مشخص شده بر می گرداند، این متد به صورت مستقیم از طریق کلاس Enumerable صدا زده می شود:

IEnumerable numbers = Enumerable.Range(1, 10);

عملگر Repeat

برای ایجاد یک مجموعه حاوی مقداری از نوع مشخص به تعداد مشخص شده استفاده می شود، این متد به صورت مستقیم از طریق کلاس Enumerable صدا زده می شود:

IEnumerable list = Enumerable.Repeat("Hi", 10);

این متد لیستی حاوی 10 عنصر با مقدار "Hi" بر می گرداند.

عملگر های Equality

این قسمت تنها یک عملگر دارد، عملگر SequenceEqual، این عملگر چک می کند دو مجموعه داده شده مقادیرشان به ترتیب با یکدیگر برابر می باشد یا خیر:

string[] list1 = { "A", "D", "B", "H", "K" };
string[] list2 = { "D", "Q", "H", "A", "B" };
string[] list3 = { "A", "D", "B", "H", "K" };
Console.WriteLine(list1.SequenceEqual(list2));
Console.WriteLine(list1.SequenceEqual(list3));

اجرای قطعه کد بالا، ابتدا مقدار False و سپس مقدار True را بر می گرداند.

عملگر های Element

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

ElementAt

از این متد برای گرفتن یک عنصر در اندیس مشخص استفاده می شود:

string[] list1 = { "A", "D", "B", "H", "K" };
Console.WriteLine(list1.ElementAt(2)); // out B

ElementAtOrDefault

مانند متد ElementAt عمل می کند، با این تفاوت که اگر اندیس داده شده خارج از بازه لیست باشد، مقدار پیش فرض نوع داده لیست را بر می گرداند.

First

اولین عنصر لیست را بر می گرداند.

FirstOrDefault

مانند عملگر First عمل کرده، با این تفاوت که اگر لیست خالی باشد مقدار پیش فرض را بر می گرداند.

Last

آخرین عنصر لیست را بر می گرداند.

LastOrDefault

مانند عملگر Last عمل کرده، با این تفاوت که اگر لیست خالی باشد مقدار پیش فرض را بر می گرداند.

Single

یکی از مقادیر لیست را بر اساس شرط مشخص شده بر می گرداند:

string[] list1 = { "A", "D", "B", "H", "K" };
string element = list1.Single(n => n.Equals("B"));

SingleOrDefault

مانند عملگر Sigle عمل کرده، با این تفاوت که در صورتی که شرط داده شده لیست خالی بر گرداند، مقدار پیش فرض را بر خواهد گرداند.

در این بخش از مقاله به بررسی تعدادی دیگر از عملگر های LINQ پرداختیم، در بخش بعدی سایر عملگر های Converting، Concatenation و Aggregation را بررسی خواهیم کرد که مباحث مربوط به عملگر های LINQ به پایان برسد.
#آموزش_linq #عملگرهای_linq #عملگرهای_استاندارد_در_linq
عنوان
1 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 1 : مقدمات رایگان
2 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 2 : پرکاربردترین ها رایگان
3 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 3 : ساختار اجرای کوئری رایگان
4 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 4 : عملگرهای استاندارد رایگان
5 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 5 : عملگرهای استاندارد رایگان
6 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 6 : عملگرهای استاندارد رایگان
7 آموزش لینک (LINQ) صفر تا صد در دات نت قسمت 7 : عملگرهای استاندارد رایگان
زمان و قیمت کل 0″ 0
0 نظر

هیچ نظری ارسال نشده است! اولین نظر برای این مطلب را شما ارسال کنید...

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره تابستانه می تونی امروز ارزونتر از فردا خرید کنی ....