Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
66
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать

Section 66.23: Joining multiple sequences

Consider entities Customer, Purchase and PurchaseItem as follows:

public class Customer

{

public string Id { get; set } // A unique Id that identifies customer public string Name {get; set; }

}

public class Purchase

{

public string Id { get; set }

public string CustomerId {get; set; } public string Description { get; set; }

}

public class PurchaseItem

{

public string Id { get; set }

public string PurchaseId {get; set; } public string Detail { get; set; }

}

Consider following sample data for above entities:

var customers = new List<Customer>()

{

new Customer() {

Id = Guid.NewGuid().ToString(), Name = "Customer1"

},

new Customer() {

Id = Guid.NewGuid().ToString(), Name = "Customer2"

}

};

var purchases = new List<Purchase>()

{

new Purchase() {

Id = Guid.NewGuid().ToString(), CustomerId = customers[0].Id, Description = "Customer1-Purchase1"

},

new Purchase() {

Id = Guid.NewGuid().ToString(), CustomerId = customers[0].Id, Description = "Customer1-Purchase2"

},

new Purchase() {

Id = Guid.NewGuid().ToString(), CustomerId = customers[1].Id, Description = "Customer2-Purchase1"

},

new Purchase() {

Id = Guid.NewGuid().ToString(),

GoalKicker.com – C# Notes for Professionals

370

CustomerId = customers[1].Id, Description = "Customer2-Purchase2"

}

};

var purchaseItems = new List<PurchaseItem>()

{

new PurchaseItem() {

Id = Guid.NewGuid().ToString(), PurchaseId= purchases[0].Id, Detail = "Purchase1-PurchaseItem1"

},

new PurchaseItem() {

Id = Guid.NewGuid().ToString(), PurchaseId= purchases[1].Id, Detail = "Purchase2-PurchaseItem1"

},

new PurchaseItem() {

Id = Guid.NewGuid().ToString(), PurchaseId= purchases[1].Id, Detail = "Purchase2-PurchaseItem2"

},

new PurchaseItem() {

Id = Guid.NewGuid().ToString(), PurchaseId= purchases[3].Id, Detail = "Purchase3-PurchaseItem1"

}

};

Now, consider below linq query:

var result = from c in

customers

 

join p in purchases on c.Id equals p.CustomerId

// first join

join pi in

purchaseItems on p.Id equals pi.PurchaseId

// second join

select new

 

 

{

 

 

c.Name,

p.Description, pi.Detail

 

};

 

 

 

 

 

To output the result of above query:

foreach(var resultItem in result)

{

Console.WriteLine($"{resultItem.Name}, {resultItem.Description}, {resultItem.Detail}");

}

The output of the query would be:

Customer1, Customer1-Purchase1, Purchase1-PurchaseItem1

Customer1, Customer1-Purchase2, Purchase2-PurchaseItem1

Customer1, Customer1-Purchase2, Purchase2-PurchaseItem2

Customer2, Customer2-Purchase2, Purchase3-PurchaseItem1

GoalKicker.com – C# Notes for Professionals

371

Live Demo on .NET Fiddle

Section 66.24: Joining on multiple keys

PropertyInfo[] stringProps = typeof (string).GetProperties();//string properties PropertyInfo[] builderProps = typeof(StringBuilder).GetProperties();//stringbuilder properties

var query =

from s in stringProps join b in builderProps

on new { s.Name, s.PropertyType } equals new { b.Name, b.PropertyType } select new

{

s.Name, s.PropertyType,

StringToken = s.MetadataToken, StringBuilderToken = b.MetadataToken

};

Note that anonymous types in above join must contain same properties since objects are considered equal only if all their properties are equal. Otherwise query won't compile.

Section 66.25: ToLookup

ToLookup returns a data structure that allows indexing. It is an extension method. It produces an ILookup instance that can be indexed or enumerated using a foreach-loop. The entries are combined into groupings at each key. - dotnetperls

string[] array = { "one", "two", "three" };

//create lookup using string length as key

var lookup = array.ToLookup(item => item.Length);

//join the values whose lengths are 3

Console.WriteLine(string.Join(",",lookup[3]));

//output: one,two

Another Example:

int[] array = { 1,2,3,4,5,6,7,8 };

//generate lookup for odd even numbers (keys will be 0 and 1) var lookup = array.ToLookup(item => item % 2);

//print even numbers after joining

Console.WriteLine(string.Join(",",lookup[0]));

//output: 2,4,6,8

//print odd numbers after joining

Console.WriteLine(string.Join(",",lookup[1]));

//output: 1,3,5,7

Section 66.26: SkipWhile

SkipWhile() is used to exclude elements until first non-match (this might be counter intuitive to most)

int[] list = { 42, 42, 6, 6, 6, 42 };

GoalKicker.com – C# Notes for Professionals

372

var result = list.SkipWhile(i => i == 42);

// Result: 6, 6, 6, 42

Section 66.27: Query Ordering - OrderBy() ThenBy()

OrderByDescending() ThenByDescending()

string[] names= { "mark", "steve", "adam" };

Ascending:

Query Syntax

var sortedNames =

from name in names orderby name select name;

Method Syntax

var sortedNames = names.OrderBy(name => name);

sortedNames contains the names in following order: "adam","mark","steve"

Descending:

Query Syntax

var sortedNames =

from name in names orderby name descending select name;

Method Syntax

var sortedNames = names.OrderByDescending(name => name);

sortedNames contains the names in following order: "steve","mark","adam"

Order by several fields

Person[] people =

{

new Person { FirstName = "Steve", LastName = "Collins", Age = 30}, new Person { FirstName = "Phil" , LastName = "Collins", Age = 28}, new Person { FirstName = "Adam" , LastName = "Ackerman", Age = 29}, new Person { FirstName = "Adam" , LastName = "Ackerman", Age = 15}

};

Query Syntax

var sortedPeople = from person in people

orderby person.LastName, person.FirstName, person.Age descending select person;

Method Syntax

GoalKicker.com – C# Notes for Professionals

373