- Where OfType<TResult> :
Описание: Оператор фильтра определяет условия, при которых возвращаются элементы. В операторе запроса Where можно использовать предикаты. Например, предикат, определяемый лямбда-выражением, возвращает логическое значение. OfType
- Select и SelectMany :
Оператор приведения используется для преобразования объекта в новый объект другого типа. Select и SelectMany определяют значение для приведения на основе результата выбора функции выбора.
- OrderBy , ЗатемПо 、По убыванию , Затем по убыванию , Обеспечить регресс :
Оператор сортировки изменяет порядок возвращаемых элементов. OrderBy сортирует по возрастанию, OrderByDescending сортирует по убыванию. Если результаты первой сортировки схожи, то для второй сортировки можно использовать операторы ThenBy и ThenByDescending. Reverse меняет порядок элементов в коллекции на обратный.
- Join 、Присоединиться к группе :
Оператор соединения используется для объединения наборов, которые не связаны напрямую. Используя оператор Join, вы можете соединить две коллекции на основе функции выбора ключа, которая аналогична функции Join в SQL. Оператор GroupJoin объединяет две коллекции, объединяя их результаты
- GroupBy 、Просмотр :
Комбинированные операторы помещают данные в группы. Оператор GroupBy объединяет элементы с общим ключом. ToLoopup объединяет элементы, создавая словарь «один ко многим».
- Any , Все , Содержит :
Оператор квантификатора возвращает логическое значение, если последовательность элементов удовлетворяет указанному условию. Любой, Все и Содержит операторы-квалификаторы. Любой определяет, удовлетворяют ли элементы коллекции функции предиката; Все определяет, удовлетворяют ли все элементы коллекции функции предиката; Содержит проверяет, существует ли элемент в коллекции. Все эти операторы возвращают логическое значение.
- Take , Пропускать , Принять во время 、Пропустить во время :
Оператор раздела возвращает подмножество коллекции. Take, Skip, TakeWhile и SkipWhile — все это операторы разделов. При использовании Take необходимо указать количество элементов, которые необходимо извлечь из коллекции; Skip пропускает указанное количество элементов и извлекает элементы; TakeWhile извлекает элементы, условия которых истинны.
- Distinct , Союз 、Пересечение , Кроме , почтовый индекс :
Оператор Set возвращает набор. Distinct удаляет повторяющиеся элементы из коллекции. Все операторы Set, кроме Distinct, требуют двух наборов. Union возвращает только элементы, которые появляются в одном из наборов. Intersect возвращает элементы, которые есть в обоих наборах. За исключением (разница) возвращает только один элемент в наборе. Zip является новым для .Net. Он объединяет два набора в один.
- First 、Первый или по умолчанию , Последний , Ластордефаулт , ЭлементВ , ЭлементАтОрдефаулт , Одинокий 、SingleOrDefault :
Эти операторы элементов возвращают только один элемент. First возвращает первый удовлетворенный элемент. FirstOrDefault аналогичен First, но возвращает значение типа по умолчанию, если не найден ни один элемент, удовлетворяющий условию. Last возвращает последний элемент, удовлетворяющий условию. ElementAt указывает позицию возвращаемого элемента. Single возвращает только один элемент, удовлетворяющий условию. Если несколько элементов удовлетворяют условию, генерируется исключение.
- Count , Сумма , мин. , Макс , Средний , Совокупность :
Агрегатные операторы вычисляют значение из коллекции. Используя эти операторы агрегирования, вы можете вычислить сумму всех значений, количество всех элементов, элемент с наибольшим и наименьшим значением и среднее значение.
-
ToArray 、ToEnumerable , К списку 、В словарь , Cast
:
Эти операторы преобразования преобразуют коллекции в массивы: IEnumerable, IList, IDictionary и т. д.
- Empty , Диапазон , Повторение :
Эти операторы генерации возвращают новую коллекцию. Коллекции пусты при использовании Empty; Range возвращает последовательность чисел; Repeat возвращает коллекцию, которая всегда повторяет значение.
- Enumerable класс Concat Метод используется для объединения двух последовательностей и возврата новой последовательности, состоящей из всех элементов двух массивов.
Формат синтаксиса:
public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first ,IEnumerable<TSource> second)
first: первая последовательность, которую нужно соединить; second: последовательность, которую нужно соединить с первой последовательностью.
Возвращаемое значение: IEnumerable
- Let Слова:
В выражениях запроса иногда бывает полезно сохранить результат выражения, чтобы его можно было использовать в последующих предложениях.
Это можно сделать с помощью ключевого слова Let, которое создает новую переменную области видимости и инициализирует измененную переменную результатом предоставленного вами выражения. Как только эта переменная области инициализируется значением, ее нельзя использовать для хранения других значений. Но если переменная области видимости хранит запрашиваемый тип, ее можно запросить.
Примеры применения:
Раздел данных:
[Serializable]
public class Team
{
public Team(string name, params int[] years)
{
this.Name = name;
this.Years = years;
}
public string Name { get; private set; }
public int[] Years { get; private set; }
}
}
[Serializable]
public class Racer : IComparable<Racer>, IFormattable
{
public Racer(string firstName = null, string lastName = null, string country = null, int starts = 0, int wins = 0, IEnumerable<int> years = null, IEnumerable<string> cars = null)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Country = country;
this.Starts = starts;
this.Wins = wins;
var yearsList = new List<int>();
foreach (var year in years)
{
yearsList.Add(year);
}
this.Years = yearsList.ToArray();
var carList = new List<string>();
foreach (var car in cars)
{
carList.Add(car);
}
this.Cars = carList.ToArray();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public int Wins { get; set; }
public int Starts { get; set; }
public string[] Cars { get; private set; }
public int[] Years { get; private set; }
public override string ToString()
{
return String.Format("{0} {1}", FirstName, LastName);
}
public int CompareTo(Racer other)
{
if (other == null) throw new ArgumentNullException("other");
return this.LastName.CompareTo(other.LastName);
}
public string ToString(string format)
{
return ToString(format, null);
}
public string ToString(string format,
IFormatProvider formatProvider)
{
switch (format)
{
case null:
case "N":
return ToString();
case "F":
return FirstName;
case "L":
return LastName;
case "C":
return Country;
case "S":
return Starts.ToString();
case "W":
return Wins.ToString();
case "A":
return String.Format("{0} {1}, {2}; starts: {3}, wins: {4}",
FirstName, LastName, Country, Starts, Wins);
default:
throw new FormatException(String.Format("Format {0} not supported", format));
}
}
}
public static class Formula1
{
private static List<Racer> racers;
public static IList<Racer> GetChampions()
{
if (racers == null)
{
racers = new List<Racer>(40);
racers.Add(new Racer("Nino", "Farina", "Italy", 33, 5, new int[] { 1950 }, new string[] { "Alfa Romeo" }));
racers.Add(new Racer("Alberto", "Ascari", "Italy", 32, 10, new int[] { 1952, 1953 }, new string[] { "Ferrari" }));
racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24, new int[] { 1951, 1954, 1955, 1956, 1957 }, new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" }));
racers.Add(new Racer("Mike", "Hawthorn", "UK", 45, 3, new int[] { 1958 }, new string[] { "Ferrari" }));
racers.Add(new Racer("Phil", "Hill", "USA", 48, 3, new int[] { 1961 }, new string[] { "Ferrari" }));
racers.Add(new Racer("John", "Surtees", "UK", 111, 6, new int[] { 1964 }, new string[] { "Ferrari" }));
racers.Add(new Racer("Jim", "Clark", "UK", 72, 25, new int[] { 1963, 1965 }, new string[] { "Lotus" }));
racers.Add(new Racer("Jack", "Brabham", "Australia", 125, 14, new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabham" }));
racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8, new int[] { 1967 }, new string[] { "Brabham" }));
racers.Add(new Racer("Graham", "Hill", "UK", 176, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" }));
racers.Add(new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" }));
racers.Add(new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" }));
racers.Add(new Racer("Emerson", "Fittipaldi", "Brazil", 143, 14, new int[] { 1972, 1974 }, new string[] { "Lotus", "McLaren" }));
racers.Add(new Racer("James", "Hunt", "UK", 91, 10, new int[] { 1976 }, new string[] { "McLaren" }));
racers.Add(new Racer("Mario", "Andretti", "USA", 128, 12, new int[] { 1978 }, new string[] { "Lotus" }));
racers.Add(new Racer("Jody", "Scheckter", "South Africa", 112, 10, new int[] { 1979 }, new string[] { "Ferrari" }));
racers.Add(new Racer("Alan", "Jones", "Australia", 115, 12, new int[] { 1980 }, new string[] { "Williams" }));
racers.Add(new Racer("Keke", "Rosberg", "Finland", 114, 5, new int[] { 1982 }, new string[] { "Williams" }));
racers.Add(new Racer("Niki", "Lauda", "Austria", 173, 25, new int[] { 1975, 1977, 1984 }, new string[] { "Ferrari", "McLaren" }));
racers.Add(new Racer("Nelson", "Piquet", "Brazil", 204, 23, new int[] { 1981, 1983, 1987 }, new string[] { "Brabham", "Williams" }));
racers.Add(new Racer("Ayrton", "Senna", "Brazil", 161, 41, new int[] { 1988, 1990, 1991 }, new string[] { "McLaren" }));
racers.Add(new Racer("Nigel", "Mansell", "UK", 187, 31, new int[] { 1992 }, new string[] { "Williams" }));
racers.Add(new Racer("Alain", "Prost", "France", 197, 51, new int[] { 1985, 1986, 1989, 1993 }, new string[] { "McLaren", "Williams" }));
racers.Add(new Racer("Damon", "Hill", "UK", 114, 22, new int[] { 1996 }, new string[] { "Williams" }));
racers.Add(new Racer("Jacques", "Villeneuve", "Canada", 165, 11, new int[] { 1997 }, new string[] { "Williams" }));
racers.Add(new Racer("Mika", "Hakkinen", "Finland", 160, 20, new int[] { 1998, 1999 }, new string[] { "McLaren" }));
racers.Add(new Racer("Michael", "Schumacher", "Germany", 250, 91, new int[] { 1994, 1995, 2000, 2001, 2002, 2003, 2004 }, new string[] { "Benetton", "Ferrari" }));
racers.Add(new Racer("Fernando", "Alonso", "Spain", 132, 21, new int[] { 2005, 2006 }, new string[] { "Renault" }));
racers.Add(new Racer("Kimi", "Räikkönen", "Finland", 148, 17, new int[] { 2007 }, new string[] { "Ferrari" }));
racers.Add(new Racer("Lewis", "Hamilton", "UK", 44, 9, new int[] { 2008 }, new string[] { "McLaren" }));
}
return racers;
}
private static List<Team> teams;
public static IList<Team> GetContructorChampions()
{
if (teams == null)
{
teams = new List<Team>()
{
new Team("Vanwall", 1958),
new Team("Cooper", 1959, 1960),
new Team("Ferrari", 1961, 1964, 1975, 1976, 1977, 1979, 1982, 1983, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008),
new Team("BRM", 1962),
new Team("Lotus", 1963, 1965, 1968, 1970, 1972, 1973, 1978),
new Team("Brabham", 1966, 1967),
new Team("Matra", 1969),
new Team("Tyrrell", 1971),
new Team("McLaren", 1974, 1984, 1985, 1988, 1989, 1990, 1991, 1998),
new Team("Williams", 1980, 1981, 1986, 1987, 1992, 1993, 1994, 1996, 1997),
new Team("Benetton", 1995),
new Team("Renault", 2005, 2006 )
};
}
return teams;
}
}
- фильтр:
Несколько выражений можно комбинировать с помощью предложения Where. Например, найдите бразильских и австрийских гонщиков, выигравших не менее 15 гонок.
- Используйте оператор Linq:
var racers = from r in Formula1.GetChampions() where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") select r;
foreach (var r in racers)
{
Console.WriteLine("{0:A}", r);
}
Результаты: Ники Лауда, Австрия, стартов: 173, побед: 25
Nelson Piquet, Brazil; starts: 204, wins: 23
Ayrton Senna, Brazil; starts: 161, wins: 41
- Используйте методы расширения
Первый способ записи: var racers = Formula1.GetChampions().Where(r => r.Wins > 15 && (r.Country == "Бразилия" || r.Country == "Австрия")).Select( г => г);
Второй способ записи: var racers = Formula1.GetChampions().Where(r => r.Wins > 15 && (r.Country == "Бразилия" || r.Country == "Австрия"));
foreach (var r in racers)
{
Console.WriteLine("{0:A}", r);
}
Результаты: Ники Лауда, Австрия, стартов: 173, побед: 25
Nelson Piquet, Brazil; starts: 204, wins: 23
Ayrton Senna, Brazil; starts: 161, wins: 41
- Фильтрация по индексу: следующий метод вызывается методом расширения Where, который использует индекс для возврата игроков, чья фамилия начинается с A и чей индекс является четным числом.
var racers =Formula1.GetChampions().Where((r, index) => r.LastName.StartsWith("A") && index % 2 != 0);
foreach (var r in racers)
{
Console.WriteLine("{0:A}", r);
}
Результаты: Альберто Аскари, Италия, стартов: 32, побед: 10
Fernando Alonso, Spain; starts: 132, wins: 21
- Тип фильтра:
Используя метод расширения OfType(), передача класса строки универсальному параметру возвращает только строки из коллекции:
object[] data = { "one", 2, 3, "four", "five", 6 };
var query = data.OfType<string>();
Результат: onefourfive |
---|
foreach (var s in query)
{
Console.WriteLine(s);
}
- в соответствии с пунктами
Класс Racer определяет свойство Cars, где Cars — это массив строк. Показать всех чемпионов за рулем Ferrari.
Первое предложение from обращается к объекту Racer, возвращаемому методом Formula1.GetChampions(), а второе предложение from обращается к свойству Cars класса Racer, чтобы вернуть все автомобили строкового типа. Затем используйте эти автомобили в предложении Where, чтобы отфильтровать всех чемпионов Ferrari.
- Написание заявления Linq:
var ferrariDrivers = from r in Formula1.GetChampions()
from c in r.Cars
where c == "Ferrari"
orderby r.LastName
select r.FirstName + " " + r.LastName;
- Написание метода расширения:
var ferrariDrivers = Formula1.GetChampions().SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c }).Where(r => r.Car == "Ferrari").OrderBy(r => r.Racer.LastName).Select(r => r.Racer.FirstName + " " + r.Racer.LastName);
- Обходим полученные результаты:
foreach (var racer in ferrariDrivers)
{
Console.WriteLine(racer);
}
Результат: Альберто Аскари
Juan Manuel Fangio
Mike Hawthorn
Phil Hill
Niki Lauda
Kimi R?ikk?nen
Jody Scheckter
Michael Schumacher
John Surtees
Предложения Conforming from и запросы LINQ преобразуются в метод расширения SelectMany(). Метод SelectMany() можно использовать для перебора последовательности последовательностей. Перегруженная версия метода SelectMany() в примере выглядит следующим образом:
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector);
Первый параметр является неявным параметром, который получает последовательность объектов Racer из метода GetChampions(). Второй параметр — это делегат CollectionSelector, который определяет внутреннюю последовательность. В лямбда-выражении r=>r.Cars
, должен вернуть коллекцию гоночных автомобилей. Третий параметр — это делегат, который теперь вызывается для каждой гоночной машины и имеет свойства Racer и Car. Результатом этого метода SelectMany() является сглаживание иерархии гонщиков и автомобилей, возвращая новую коллекцию объектов анонимного типа для каждого автомобиля.
Разберите общий метод SelectMany() на тип использования здесь; источником данных является тип Racer, отфильтрованная коллекция представляет собой массив строк, когда имя возвращаемого анонимного типа неизвестно, оно отображается здесь как TResult;
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<Racer> source,
Func<Racer, IEnumerable<string>> collectionSelector,
Func<Racer, string, TResult> resultSelector);
- Сортировать:
- Линк пишет:
var query = from r in Formula1.GetChampions()
where r.Country == "Brazil"
orderby r.Wins descending
select r;
- метод расширения:
Первый: query= Formula1.GetChampions().Where(r => r.Country == "Бразилия").OrderByDescending(r => r.Wins).Select(r=>r);
Второй: var query= Formula1.GetChampions().Where(r => r.Country == "Бразилия").OrderByDescending(r => r.Wins);
- Просмотрите результаты: foreach (var r в запросе)
{
Console.WriteLine("{0:A}", r);
}
Результаты: Айртон Сенна, Бразилия, стартов: 161, побед: 41
elson Piquet, Brazil; starts: 204, wins: 23
merson Fittipaldi, Brazil; starts: 143, wins: 14
Методы OrderBy и OrderByDescending() возвращают IOrderEnumerable
var racers=(из r в Formula1.GetChampions() orderby r.Country,r.LastName, r.FirstName select r).Take(10);//метод расширения Take(10) используется для извлечения первых 10 результатов.
Используйте методы расширения:
var racers= Formula1.GetChampions().OrderBy(r=>r.Country).ThenBy(r.LastName).ThenBy(r=>r.FirstName).Take(10);
- Группировка:
- Способ написания Linq:
Используйте предложение Group для группировки по странам и перечислите количество чемпионов в стране. Сгруппируйте r по r.Country в g. Объедините всех игроков в соответствии со свойством Country и добавьте новый идентификатор g, который позже будет использоваться для доступа к результату. информация группы. Результат предложения Group сортируется путем применения метода расширения Count() к результату группировки.Если количество чемпионов одинаковое, он сортируется по ключевому слову, которое является страной, потому что это используемое ключевое слово для группировки. Предложение Where фильтрует результаты на основе групп из не менее двух элементов, а предложение Select создает анонимный тип со свойствами Country и count.
var countries = from r in Formula1.GetChampions()
group r by r.Country into g
orderby g.Count() descending, g.Key
where g.Count() >= 2
select new
{
Country = g.Key,
Count = g.Count()
};
- Использование методов расширения: чтобы сделать то же самое с методами расширения, предложение GroupBy должно быть преобразовано в метод GroupBy(). Обратите внимание, что в объявлении метода GroupBy() он возвращает объект, реализующий интерфейс IGrouping. Интерфейс IGrouping определяет свойство Key, поэтому после определения вызова этого метода можно получить доступ к ключу группировки.
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
Разберите группу предложений r по r.Country в g как GroupBy (r=>r.Country) и верните последовательность группировки. Последовательность группировки сначала сортируется методом OrderByDescending(), а затем сортируется методом ThenBy(). Затем вызовите методы Where() и Select().
var countries = Formula1.GetChampions().GroupBy(r => r.Country).OrderByDescending(g => g.Count()).ThenBy(g => g.Key).Where(g => g.Count() >= 2).Select(g => new
{
Country = g.Key,
Count= g.Count()
});
- Просмотрите результаты: foreach (элемент var в странах)
{
Console.WriteLine("{0, -10} {1}", item.Country, item.Count);
}
Результат: Великобритания 9
Brazil 3
Finland 3
Australia 2
Austria 2
Italy 2
USA 2
- Группировать вложенные объекты:
Если сгруппированные объекты должны содержать вложенные последовательности, вы можете изменить анонимный тип, созданный предложением Select. В приведенном ниже примере возвращенная страна содержит не только атрибуты названия страны и количества игроков, но и последовательность имен игроков. Последовательность задается внутренним предложением from/in, которое присваивает свойство Racers.Внутреннее предложение from использует идентификатор группы g, чтобы получить всех гонщиков в группе, отсортировать их по фамилии, а затем создать новую строку на основе название.
- Способ написания Linq:
var countries = from r in Formula1.GetChampions()
group r by r.Country into g
orderby g.Count() descending, g.Key
where g.Count() >= 2
select new
{
Country = g.Key,
Count = g.Count(),
Racers = from r1 in g
orderby r1.LastName
select r1.FirstName + " " + r1.LastName
};
- Как написать метод расширения:
var countries = Formula1.GetChampions().GroupBy(r => r.Country).OrderByDescending(r => r.Count()).ThenBy(r => r.Key).Where(r => r.Count() >= 2).Select(r =>
new
{
Country = r.Key,
Count = r.Count(),
Racers = r.OrderBy(g => g.LastName).Select(g => g.FirstName + " " + g.LastName)
});
- Перебрать полученные результаты:
foreach (var item in countries)
{
Console.WriteLine("{0, -10} {1}", item.Country, item.Count);
foreach (var name in item.Racers)
{
Console.Write("{0}; ", name);
}
Console.WriteLine();
}
результат:
UK 9
Jim Clark; Lewis Hamilton; Mike Hawthorn; Graham Hill; Damon Hill; James Hunt; N
igel Mansell; Jackie Stewart; John Surtees;
Brazil 3
Emerson Fittipaldi; Nelson Piquet; Ayrton Senna;
Finland 3
Mika Hakkinen; Kimi R?ikk?nen; Keke Rosberg;
Australia 2
Jack Brabham; Alan Jones;
Austria 2
Niki Lauda; Jochen Rindt;
Italy 2
Alberto Ascari; Nino Farina;
USA 2
Mario Andretti; Phil Hill;
- соединять:
Используйте предложение соединения для объединения двух источников данных на основе определенных условий, но до объединения двух списков. В Формуле-1 есть чемпионаты пилотов и чемпионаты конструкторов. Гонщики возвращаются из метода GetContructorChampions() и теперь получают список за год, в котором перечислены чемпион гонщика и чемпионат команды. Для этого сначала определите два запроса для запроса автомобилей и команд.
var racers = from r in Formula1.GetChampions()
from y in r.Years
where y > 2003
select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};
var teams = from t in
Formula1.GetContructorChampions()
from y in t.Years
where y > 2003
select new
{
Year = y,
Name = t.Name
};
С помощью этих двух запросов объедините r в командах по r.Year равно t.Year словами присоединить r к командам по r.Year равно t.Year, исходя из года, когда гонщик выиграл чемпионат, и года, когда команда выиграла чемпионат. . Предложение Select определяет новый анонимный тип со свойствами Year, Racer и Team.
var racersAndTeams =
from r in racers
join t in teams on r.Year equals t.Year
select new
{
Year = r.Year,
Racer = r.Name,
Team = t.Name
};
Объедините вышеперечисленное в один запрос Linq
var racersAndTeams = from r in
from r1 in Formula1.GetChampions() from yr in r1.Years
where yr > 2003
select new
{
Year = yr,
Name = r1.FirstName + " " + r1.LastName
}
join t in
from t1 in Formula1.GetContructorChampions() from yt in t1.Years
where yt > 2003
select new
{
Year = yt,
Name = t1.Name
}
on r.Year equals t.Year
select new
{
Year=r.Year,
Racer=r.Name,
Team=t.Name
};
Console.WriteLine("Year Champion " + "Constructor Title");
foreach (var item in racersAndTeams)
{
Console.WriteLine("{0}: {1,-20} {2}",
item.Year, item.Racer, item.Team);
}
результат:
Year Champion Constructor Title
2004: Michael Schumacher Ferrari
2005: Fernando Alonso Renault
2006: Fernando Alonso Renault
2007: Kimi R?ikk?nen Ferrari
2008: Lewis Hamilton Ferrari
-
Операции по сбору:
Все методы расширения Distinct(), Union(), Intersect() и Except() являются операциями над множествами. Затем создайте последовательность чемпионата Формулы-1 с Ferrari и последовательность чемпионата Формулы-1 с McLaren, а затем определите, есть ли чемпионат с Ferrari и McLaren. Конечно, вы можете использовать метод расширения Intersect().
- Получить все чемпионаты за рулем Ferrari:
var ferrariDrivers = from r in Formula1.GetChampions()
from c in r.Cars
where c == "Ferrari"
orderby r.LastName
select r;
- Напишите публичный метод, чтобы все чемпионы ездили на McLaren.
private static IEnumerable<Racer> GetRacerByCar(string car)
{
return from r in Formula1.GetChampions() from c in r.Cars where c==car orderby r.LastName select r;
}
Поскольку она больше нигде не используется, определена переменная типа делегата для хранения запроса Linq. Переменная racerByCar должна быть типом делегата, для которого требуется строковый параметр и которая возвращает IEnumerable
Func<string, IEnumerable<Racer>> racersByCar =
car => from r in Formula1.GetChampions()
from c in r.Cars
where c == car
orderby r.LastName
select r;
Console.WriteLine("World champion with Ferrari and McLaren");
foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
{
Console.WriteLine(racer);
}
результат:
World champion with Ferrari and McLaren
Niki Lauda
- сливаться
Метод Zip() является новым для .Net и позволяет объединять две связанные последовательности с функцией предиката. Сначала создайте две связанные последовательности, использующие один и тот же метод фильтрации и сортировки. Для слияния это важно, поскольку первый элемент первой коллекции объединяется с первым элементом второй коллекции, а второй элемент первой коллекции объединяется со вторым элементом второй коллекции и так далее. Если две последовательности не идентичны, Zip() останавливается в конце меньшего набора.
Элементы первой коллекции имеют свойство Name, а элементы второй коллекции — свойства LastName и Starts.
Для использования метода Zip() в коллекции racerName требуется вторая коллекция (racerNameAndStarts) в качестве первого параметра. Тип второго параметра — Func
var racerNames = from r in Formula1.GetChampions()
where r.Country == "Italy"
orderby r.Wins descending
select new
{
Name = r.FirstName + " " + r.LastName
};
var racerNamesAndStarts = from r in Formula1.GetChampions()
where r.Country == "Italy"
orderby r.Wins descending
select new
{
LastName = r.LastName,
Starts = r.Starts
};
Результат: Альберто Аскари, стартов: 32Нино Фарина, стартов: 33 |
---|
var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ", starts: " + second.Starts);
foreach (var r in racers)
{
Console.WriteLine(r);
}
- раздел
Операции с разделами, такие как методы расширения Take() и Skip(), можно использовать для разбиения на страницы, например, для отображения гонщиков 5×5.
Пример. Метод Skip сначала игнорирует количество элементов, рассчитанное на основе размера страницы и фактического количества страниц, а затем использует метод Take() для извлечения определенного количества элементов на основе размера страницы;
int pageSize = 5;
int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() /
(double)pageSize);
for (int page = 0; page < numberPages; page++)
{
Console.WriteLine("Page {0}", page);
var racers =
(from r in Formula1.GetChampions()
orderby r.LastName
select r.FirstName + " " + r.LastName).
Skip(page * pageSize).Take(pageSize);
foreach (var name in racers)
{
Console.WriteLine(name);
}
Console.WriteLine();
}
результат:
Page 0
Fernando Alonso
Mario Andretti
Alberto Ascari
Jack Brabham
Jim Clark
Page 1
Juan Manuel Fangio
Nino Farina
Emerson Fittipaldi
Mika Hakkinen
Lewis Hamilton
Page 2
Mike Hawthorn
Phil Hill
Graham Hill
Damon Hill
Denny Hulme
Page 3
James Hunt
Alan Jones
Niki Lauda
Nigel Mansell
Nelson Piquet
Page 4
Alain Prost
Kimi R?ikk?nen
Jochen Rindt
Keke Rosberg
Jody Scheckter
Page 5
Michael Schumacher
Ayrton Senna
Jackie Stewart
John Surtees
Jacques Villeneuve
- Агрегатный оператор
**** Агрегирующие операторы, такие как count(), Sum(), Min(), Max(), Average() и Aggregate(), возвращают одно значение.
- Следующий Count() используется для свойства Racer's Years. Возвращает участника с более чем 3 морфемами чемпионата.
var query = from r in Formula1.GetChampions()
where r.Years.Count() > 3
orderby r.Years.Count() descending
select new
{
Name = r.FirstName + " " + r.LastName,
TimesChampion = r.Years.Count()
};
foreach (var r in query)
{
Console.WriteLine("{0} {1}", r.Name, r.TimesChampion);
}
Результаты: Михаэль Шумахер 7
Juan Manuel Fangio 5
Alain Prost 4
- Метод Sum() суммирует все числа в последовательности и возвращает сумму этих чисел. Ниже показан метод Sun(), используемый для подсчета общего количества побед страны в игре. Сначала игроки группируются по стране, а затем во вновь созданном анонимном типе атрибуту «Выигрыши» присваивается общее количество раз, когда страна выиграла.
var countries = (from c in from r in Formula1.GetChampions() group r by r.Country into c select new
{
Country = c.Key,
Wins = (from r1 in c select r1.Wins).Sum()
}
orderby c.Wins descending, c.Country
select c).Take(5);
foreach (var country in countries)
{
Console.WriteLine("{0} {1}", country.Country, country.Wins);
}
Результат: Великобритания 147
Germany 91
Brazil 78
France 51
Finland 42
- Конвертировать:
Когда запрос используется в итерации, запрос выполняется. Использование оператора преобразования немедленно выполняет запрос, помещая результаты запроса в список массивов или словарь.
Пример: вызывается метод расширения ToList, запрос выполняется немедленно, и полученный результат помещается в класс List
List<Racer> racers=(from r in Formula1.GetChampions() where r.Starts>150 orderby r.Starts descending select r).ToList();
Foreach( var racer in racers)
{
Console.WriteLine("{0} {0:S}",гонщик);
}
Поместить возвращенный объект в список не так просто. Например, для быстрого доступа от гоночной машины к гонщику в коллекции можно использовать новый класс Lookup
Примечание. Класс Dictionary
Используя соответствующий запрос, последовательность гонщика и гонщика можно сгладить, создав анонимный тип со свойствами Car и Racer. В возвращаемом объекте Lookup тип ключа video представляет строку автомобиля, а тип значения video — Racer. Чтобы разбудить выделение, вы можете передать ключ и селектор элемента в перегруженную версию метода ToLookup(). Ключевой селектор относится к свойству Car, а селектор элемента — к свойству Racer.
var racers = (from r in Formula1.GetChampions()
from c in r.Cars
select new
{Car =c,
Racer=r}).ToLookup(cr=>cr.Car,cr=>cr.Racer);
if (racers.Contains("Williams"))
{
foreach (var williamsRacer in racers["Williams"])
{
Console.WriteLine(williamsRacer);
}
}
Результаты: Алан Джонс
Keke Rosberg
Nelson Piquet
Nigel Mansell
Alain Prost
Damon Hill
Jacques Villeneuve
Если вам нужно использовать Linq для запросов к нетипизированным коллекциям (таким как ArrayList), вы можете использовать метод Cast(). Пример. Коллекция ArrayList, основанная на типе Object, заполняется объектами Racer. Для определения строго типизированных запросов можно использовать метод Cast().
var list = new System.Collections.ArrayList(Formula1.GetChampions() as System.Collections.ICollection);
var query = from r in list.Cast<Racer>()
where r.Country == "USA"
orderby r.Wins descending
select r;
foreach (var racer in query)
{
Console.WriteLine("{0:A}", racer);
}
Выходной результат:
Mario Andretti, USA; starts: 128, wins: 12
Phil Hill, USA; starts: 48, wins: 3
- Сгенерировать оператор.
**** Операции генерации Range(), Empty() и Repeat() не являются методами расширения, а являются обычными статическими методами, которые возвращают последовательности. В Linq to object эти методы используются в классе Enumerable. Иногда необходимо заполнить диапазон чисел, и в этом случае следует использовать метод Range(). Этот метод принимает первый параметр в качестве начального значения, а второй параметр — количество элементов для заполнения.
var values=Enumerable.Range(1,20);
foreach( var item in values)
{
Console.Write("{0}",item);
}
Результаты: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Примечание: метод Range() не возвращает коллекцию, заполненную определенными значениями.Этот метод, как и другие методы, откладывает выполнение запроса и возвращает RangeEnumerator только с оператором yield return для увеличения. Вы можете объединить этот результат с методом расширения, чтобы получить другой результат, например метод расширения Select().
Var values=Enumerable.Range(1,20).Select(n=>n*3);
Метод Empty() возвращает итератор без значения, который можно использовать для параметров, требующих коллекции, где параметр может быть проколот пустой коллекцией.
Метод Repeat() возвращает итератор, который повторяет одно и то же значение заданное количество раз.
15 , Linq реализует не в а в условных запросах в sql
1. В запросе состояния
var queryResult = from p in db.Products
where (new int?[] {1,2}).Contains(p.CategoryID)
select p;
2. Не в условном запросе
var queryResult = from p in db.Products
where ! (new int?[] {1,2}).Contains(p.CategoryID)
select p;