
October 27, 2010 23:19 by
Mikie
როგორც მოგვეხსენება LINQ ტექნოლოგია არჭურვილია ორი მიმდევრობის და - Join - ების ისეთივე შესაძლებლობით როგორც გვაქვს რელაციურ მონაცემთა ბაზებში.
შემდები რამდენიმე მაგალითით მინდა წარმოგიდგინოთ თუ როგორ შეიძლება C# - ში ორი დინამიური მიმდევრობისთვის join ოპერატორის მიყენება.
პირველი და ყველაზე მარტივი მაგალითი
One-to-One Join (ერთი ერთთან)
string[] arr1 = new string[] { "a", "b", "c", "d" };
string[] arr2 = new string[] { "b", "c", "d", "e" };
var q = from s1 in arr1
join s2 in arr2 on s1 equals s2
select string.Format("arr1: {0} arr2: {1}", s1, s2);
foreach (string s in q)
{
Response.Write(s + "<br />");
}
შედეგი რა თქმა უნდა აშკარაა, (ერთ მიმდევრობაში ვეძებთ მეორე მიმდევრობის შესაბამის ელემებტებს):
| arr1: |
b |
arr2: |
b |
| arr1: |
c |
arr2: |
c |
| arr1: |
d |
arr2: |
d |
Customer - ებისა და მათი შესაბამისი Order - ების სიას (One-to-One ბრტყელ რეჟიმში). გადაბმული Customer ID - თი
var customers = Customer.SampleData();
var orders = Order.SampleData();
var q = from o in orders join
c in customers on o.Customer equals c.ID
select new
{
Order = o.ID,
Customer = c.Name
};
foreach (var o in q)
{
Console.WriteLine("Customer: {0} Order Number: {1}", o.Customer, o.Order);
}
| Customer: Carlos González Order Number: 10461 |
| Customer: Carlos González Order Number: 10381 |
| Customer: Carlos González Order Number: 10499 |
| Customer: José Pedro Freyre Order Number: 10874 |
| Customer: José Pedro Freyre Order Number: 10911 |
| Customer: Mary Saveley Order Number: 10843 |
| Customer: Renate Messner Order Number: 10862 |
| Customer: Renate Messner Order Number: 10772 |
| Customer: Rene Phillips Order Number: 11034 |
| Customer: Rene Phillips Order Number: 10305 |
| Customer: Rene Phillips Order Number: 10338 |
| Customer: Rene Phillips Order Number: 10680 |
ზედას ანალოგიური მაგალითი DefaultIfEmpty() - ს გამოყენებით, ანუ იმ შემთხვევაში თუ არ გვექნა შეკვეთა რომელიმე მომხმარებელზე შედეგად გვერქნება
null
var customers = Customer.SampleData();
var orders = Order.SampleData();
var q = from c in customers
join o in orders on
new { Customer = c.ID } equals new { Customer = o.Customer }
into res
from order in res.DefaultIfEmpty()
select new
{
Customer = c.Name,
Order = order == null ? "(no order) " : order.ID.ToString()
};
foreach (var o in q)
{
Console.WriteLine("Customer: {0} Order Number: {1}", o.Customer, o.Order);
}
| Customer: Maria Anders Order Number: (no order) |
| Customer: Ana Trujillo Order Number: 10759 |
| Customer: Ana Trujillo Order Number: 10926 |
| Customer: Thomas Hardy Order Number: (no order) |
| Customer: Christina Berglund Order Number: 10278 |
| Customer: Christina Berglund Order Number: 10280 |
| Customer: Christina Berglund Order Number: 10384 |
მინდა მივაქციო თქვენი ყურადღება 2 დეტალზე:
1. equals ოპერატორთან ბმა გამოყენებულია new ოპერატორის მეშვეობით, ანუ ეს ნიშნავს იმას რომ გადაბმისთვის შესაძლებელია Composite Key - ების გამოყენება (ანუ რთული გამოსახულებების, მაგალითად არა ID არამედ სახელი და გვარით).
2. select ... into res. პრაქტიკულად გამოცხადებულია დროებითი Anonymous ტიპის ცვლადი რომელშიც ვინახავ ჩემს შედეგს.
One-to-Many
ქვემოთ მოყვანილია 4 მაგალითი იმისა თუ რა მეთოდებით შეიძლება გაკეთდეს LINQ - ით One-to-Many ბმა.
1. ჩვეულებრივი select
var q = from c in customers join
o in orders on c.ID equals o.Customer
into CustomerOrders
select new
{
Customer = c.Name,
Orders = CustomerOrders
};
2. GroupJoin() მეთოდი
var q = customers.GroupJoin(orders,
c => c.ID,
o => o.Customer,
(c, o) => new
{
Customer = c.Name,
Orders = o
});
3. ჩადგმული select
var q = from c in customers
select new
{
Customer = c.Name,
Orders = from o in orders where o.Customer == c.ID select o
};
4. ToLookup() მეთოდი
var OrdersLookup = orders.ToLookup(o => o.Customer);
var q = from c in customers
select new
{
Customer = c.Name,
Orders = OrdersLookup[c.ID]
};
ToLookup() აგრუპირებს შეკვეთებს მომხმარებლის მიხედვით და შემდგომი select - ი არჩევს მათ დაგრუპირებული key - ს მიხედვით.
შედეგი?
ერთი და იგივე:
| Rene Phillips |
| - Order Number: 10305 |
| - Order Number: 10965 |
| - Order Number: 11034 |
| Victoria Ashworth |
| - Order Number: 11023 |
| Martine Rancé |
| - Order Number: 10408 |
| - Order Number: 10480 |
სხვაობა?
შესრულების დრო (1 მილიონი იტერაცია)
| join into ან GroupJoin |
ჩადგმული select |
ToLookUp() |
| 21562 მწ |
20179 მწ |
17928 მწ |
P.S. მოცემულ პროექტში შეგიძლია იხილოთ თითოული ზომთ აღწერილი მაგალითი
LinqToObjects.rar (52.67 kb)
acfd5574-9523-418b-9a57-01bf501260ac|0|.0