Самый сильный обзор стандартных операторов Linq To Object

искусственный интеллект
  1. Where OfType<TResult> :

Описание: Оператор фильтра определяет условия, при которых возвращаются элементы. В операторе запроса Where можно использовать предикаты. Например, предикат, определяемый лямбда-выражением, возвращает логическое значение. OfType фильтрует элементы по типу и возвращает только элементы типа TResult.

  1. Select и SelectMany :

Оператор приведения используется для преобразования объекта в новый объект другого типа. Select и SelectMany определяют значение для приведения на основе результата выбора функции выбора.

  1. OrderBy , ЗатемПо 、По убыванию , Затем по убыванию , Обеспечить регресс :

Оператор сортировки изменяет порядок возвращаемых элементов. OrderBy сортирует по возрастанию, OrderByDescending сортирует по убыванию. Если результаты первой сортировки схожи, то для второй сортировки можно использовать операторы ThenBy и ThenByDescending. Reverse меняет порядок элементов в коллекции на обратный.

  1. Join 、Присоединиться к группе :

Оператор соединения используется для объединения наборов, которые не связаны напрямую. Используя оператор Join, вы можете соединить две коллекции на основе функции выбора ключа, которая аналогична функции Join в SQL. Оператор GroupJoin объединяет две коллекции, объединяя их результаты

  1. GroupBy 、Просмотр :

Комбинированные операторы помещают данные в группы. Оператор GroupBy объединяет элементы с общим ключом. ToLoopup объединяет элементы, создавая словарь «один ко многим».

  1. Any , Все , Содержит :

Оператор квантификатора возвращает логическое значение, если последовательность элементов удовлетворяет указанному условию. Любой, Все и Содержит операторы-квалификаторы. Любой определяет, удовлетворяют ли элементы коллекции функции предиката; Все определяет, удовлетворяют ли все элементы коллекции функции предиката; Содержит проверяет, существует ли элемент в коллекции. Все эти операторы возвращают логическое значение.

  1. Take , Пропускать , Принять во время 、Пропустить во время :

Оператор раздела возвращает подмножество коллекции. Take, Skip, TakeWhile и SkipWhile — все это операторы разделов. При использовании Take необходимо указать количество элементов, которые необходимо извлечь из коллекции; Skip пропускает указанное количество элементов и извлекает элементы; TakeWhile извлекает элементы, условия которых истинны.

  1. Distinct , Союз 、Пересечение , Кроме , почтовый индекс :

Оператор Set возвращает набор. Distinct удаляет повторяющиеся элементы из коллекции. Все операторы Set, кроме Distinct, требуют двух наборов. Union возвращает только элементы, которые появляются в одном из наборов. Intersect возвращает элементы, которые есть в обоих наборах. За исключением (разница) возвращает только один элемент в наборе. Zip является новым для .Net. Он объединяет два набора в один.

  1. First 、Первый или по умолчанию , Последний , Ластордефаулт , ЭлементВ , ЭлементАтОрдефаулт , Одинокий 、SingleOrDefault :

Эти операторы элементов возвращают только один элемент. First возвращает первый удовлетворенный элемент. FirstOrDefault аналогичен First, но возвращает значение типа по умолчанию, если не найден ни один элемент, удовлетворяющий условию. Last возвращает последний элемент, удовлетворяющий условию. ElementAt указывает позицию возвращаемого элемента. Single возвращает только один элемент, удовлетворяющий условию. Если несколько элементов удовлетворяют условию, генерируется исключение.

  1. Count , Сумма , мин. , Макс , Средний , Совокупность :

Агрегатные операторы вычисляют значение из коллекции. Используя эти операторы агрегирования, вы можете вычислить сумму всех значений, количество всех элементов, элемент с наибольшим и наименьшим значением и среднее значение.

  1. ToArray 、ToEnumerable , К списку 、В словарь , Cast :

Эти операторы преобразования преобразуют коллекции в массивы: IEnumerable, IList, IDictionary и т. д.

  1. Empty , Диапазон , Повторение :

Эти операторы генерации возвращают новую коллекцию. Коллекции пусты при использовании Empty; Range возвращает последовательность чисел; Repeat возвращает коллекцию, которая всегда повторяет значение.

  1. Enumerable класс Concat Метод используется для объединения двух последовательностей и возврата новой последовательности, состоящей из всех элементов двух массивов.

Формат синтаксиса:

public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first ,IEnumerable<TSource> second)

first: первая последовательность, которую нужно соединить; second: последовательность, которую нужно соединить с первой последовательностью.

Возвращаемое значение: IEnumerable, содержащий элементы двух входных последовательностей.

  1. 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;

        }

}

  1. фильтр:

Несколько выражений можно комбинировать с помощью предложения 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

  1. Фильтрация по индексу: следующий метод вызывается методом расширения 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

  1. Тип фильтра:

Используя метод расширения OfType(), передача класса строки универсальному параметру возвращает только строки из коллекции:

object[] data = { "one", 2, 3, "four", "five", 6 };

            var query = data.OfType<string>();

 

Результат: onefourfive

            foreach (var s in query)

 

            {

                Console.WriteLine(s);

                }

  1. в соответствии с пунктами

Класс Racer определяет свойство Cars, где Cars — это массив строк. Показать всех чемпионов за рулем Ferrari.

Первое предложение from обращается к объекту Racer, возвращаемому методом Formula1.GetChampions(), а второе предложение from обращается к свойству Cars класса Racer, чтобы вернуть все автомобили строкового типа. Затем используйте эти автомобили в предложении Where, чтобы отфильтровать всех чемпионов Ferrari.

  1. Написание заявления Linq:

   var ferrariDrivers = from r in Formula1.GetChampions()

                                 from c in r.Cars

                                 where c == "Ferrari"

                                 orderby r.LastName

                                 select r.FirstName + " " + r.LastName;

  1. Написание метода расширения:

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);

  1. Обходим полученные результаты:

            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);

  1. Сортировать:
  1. Линк пишет:

var query = from r in Formula1.GetChampions()

                        where r.Country == "Brazil"

                        orderby r.Wins descending

                        select r;

  1. метод расширения:

Первый: 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);

  1. Просмотрите результаты: 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. Этот интерфейс является производным от IEnumerable(), и этот метод используется для дальнейшей сортировки последовательности. Если упорядочивание основано на селекторе ключевых слов и два из них совпадают, то упорядочивание можно продолжить с помощью методов ThenBy() и ThenByDescending(). Для работы этих двух методов требуется интерфейс IOrderEnumerable, но они также возвращают этот интерфейс. Таким образом, вы можете добавить любое количество методов ThenBy() и ThenByDescending() для сортировки коллекции.

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);

  1. Группировка:
  1. Способ написания 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()

                            };           

  1. Использование методов расширения: чтобы сделать то же самое с методами расширения, предложение 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()

            });

  1. Просмотрите результаты: foreach (элемент var в странах)

             {

                Console.WriteLine("{0, -10} {1}", item.Country, item.Count);

                 }

Результат: Великобритания 9

    Brazil       3

           Finland      3

           Australia     2

           Austria       2

           Italy         2

           USA         2

  1. Группировать вложенные объекты:

Если сгруппированные объекты должны содержать вложенные последовательности, вы можете изменить анонимный тип, созданный предложением Select. В приведенном ниже примере возвращенная страна содержит не только атрибуты названия страны и количества игроков, но и последовательность имен игроков. Последовательность задается внутренним предложением from/in, которое присваивает свойство Racers.Внутреннее предложение from использует идентификатор группы g, чтобы получить всех гонщиков в группе, отсортировать их по фамилии, а затем создать новую строку на основе название.

  1. Способ написания 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

                            };

  1. Как написать метод расширения:

   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)

                       });

  1. Перебрать полученные результаты:

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. соединять:

Используйте предложение соединения для объединения двух источников данных на основе определенных условий, но до объединения двух списков. В Формуле-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

  1. Операции по сбору:
    Все методы расширения Distinct(), Union(), Intersect() и Except() являются операциями над множествами. Затем создайте последовательность чемпионата Формулы-1 с Ferrari и последовательность чемпионата Формулы-1 с McLaren, а затем определите, есть ли чемпионат с Ferrari и McLaren. Конечно, вы можете использовать метод расширения Intersect().
  1. Получить все чемпионаты за рулем Ferrari:

var ferrariDrivers = from r in Formula1.GetChampions()

                                from c in r.Cars

                                where c == "Ferrari"

                                orderby r.LastName

                                    select r;

  1. Напишите публичный метод, чтобы все чемпионы ездили на 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, подобно методу, реализованному ранее. Для этой цели определено несколько универсальных делегатов Fun, поэтому нет необходимости объявлять собственный делегат. Назначьте лямбда-выражение переменной racerByCar. Левая часть лямбда-выражения определяет переменную car, тип которой является первым общим параметром делегата Func (строка). Правая часть определяет запрос Linq, который использует этот параметр и предложение Where:

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

 

  1. сливаться

Метод Zip() является новым для .Net и позволяет объединять две связанные последовательности с функцией предиката. Сначала создайте две связанные последовательности, использующие один и тот же метод фильтрации и сортировки. Для слияния это важно, поскольку первый элемент первой коллекции объединяется с первым элементом второй коллекции, а второй элемент первой коллекции объединяется со вторым элементом второй коллекции и так далее. Если две последовательности не идентичны, Zip() останавливается в конце меньшего набора.

Элементы первой коллекции имеют свойство Name, а элементы второй коллекции — свойства LastName и Starts.

Для использования метода Zip() в коллекции racerName требуется вторая коллекция (racerNameAndStarts) в качестве первого параметра. Тип второго параметра — Func. Этот параметр реализован как лямбда-выражение, которое получает элементы первой коллекции через параметр first и элемент второй коллекции через параметр second, а код его реализации создает и возвращает строку, содержащую элементы первой коллекции. Свойство Name элемента и свойство Starts элементов второй коллекции:

  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);

                }

  1. раздел

Операции с разделами, такие как методы расширения 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

  1. Агрегатный оператор

**** Агрегирующие операторы, такие как count(), Sum(), Min(), Max(), Average() и Aggregate(), возвращают одно значение.

  1. Следующий 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

  1. Метод 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

  1. Конвертировать:

Когда запрос используется в итерации, запрос выполняется. Использование оператора преобразования немедленно выполняет запрос, помещая результаты запроса в список массивов или словарь.

Пример: вызывается метод расширения 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 поддерживает только один ключ, соответствующий одному значению. В классе Lookup пространства имен System.Linq ключ может соответствовать нескольким значениям.

Используя соответствующий запрос, последовательность гонщика и гонщика можно сгладить, создав анонимный тип со свойствами 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

  1. Сгенерировать оператор.

**** Операции генерации 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;