Using linq in windows forms

Language Integrated Query (LINQ)

Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language. Traditionally, queries against data are expressed as simple strings without type checking at compile time or IntelliSense support. Furthermore, you have to learn a different query language for each type of data source: SQL databases, XML documents, various Web services, and so on. With LINQ, a query is a first-class language construct, just like classes, methods, events.

For a developer who writes queries, the most visible «language-integrated» part of LINQ is the query expression. Query expressions are written in a declarative query syntax. By using query syntax, you can perform filtering, ordering, and grouping operations on data sources with a minimum of code. You use the same basic query expression patterns to query and transform data in SQL databases, ADO .NET Datasets, XML documents and streams, and .NET collections.

The following example shows the complete query operation. The complete operation includes creating a data source, defining the query expression, and executing the query in a foreach statement.

Query expression overview

Query expressions can be used to query and to transform data from any LINQ-enabled data source. For example, a single query can retrieve data from a SQL database, and produce an XML stream as output.

Query expressions are easy to master because they use many familiar C# language constructs.

The variables in a query expression are all strongly typed, although in many cases you do not have to provide the type explicitly because the compiler can infer it. For more information, see Type relationships in LINQ query operations.

A query is not executed until you iterate over the query variable, for example, in a foreach statement. For more information, see Introduction to LINQ queries.

At compile time, query expressions are converted to Standard Query Operator method calls according to the rules set forth in the C# specification. Any query that can be expressed by using query syntax can also be expressed by using method syntax. However, in most cases query syntax is more readable and concise. For more information, see C# language specification and Standard query operators overview.

As a rule when you write LINQ queries, we recommend that you use query syntax whenever possible and method syntax whenever necessary. There is no semantic or performance difference between the two different forms. Query expressions are often more readable than equivalent expressions written in method syntax.

Some query operations, such as Count or Max, have no equivalent query expression clause and must therefore be expressed as a method call. Method syntax can be combined with query syntax in various ways. For more information, see Query syntax and method syntax in LINQ.

Query expressions can be compiled to expression trees or to delegates, depending on the type that the query is applied to. IEnumerable queries are compiled to delegates. IQueryable and IQueryable queries are compiled to expression trees. For more information, see Expression trees.

Next steps

To learn more details about LINQ, start by becoming familiar with some basic concepts in Query expression basics, and then read the documentation for the LINQ technology in which you are interested:

ADO.NET Entity Framework: LINQ to entities

.NET collections, files, strings and so on: LINQ to objects

To gain a deeper understanding of LINQ in general, see LINQ in C#.

To start working with LINQ in C#, see the tutorial Working with LINQ.

Using linq in windows forms

LINQ (Language-Integrated Query) представляет простой и удобный язык запросов к источнику данных. В качестве источника данных может выступать объект, реализующий интерфейс IEnumerable (например, стандартные коллекции, массивы), набор данных DataSet, документ XML. Но вне зависимости от типа источника LINQ позволяет применить ко всем один и тот же подход для выборки данных.

Существует несколько разновидностей LINQ:

LINQ to Objects : применяется для работы с массивами и коллекциями

LINQ to Entities : используется при обращении к базам данных через технологию Entity Framework

LINQ to Sql : технология доступа к данным в MS SQL Server

LINQ to XML : применяется при работе с файлами XML

LINQ to DataSet : применяется при работе с объектом DataSet

Parallel LINQ (PLINQ) : используется для выполнения параллельных запросов

В этой главе речь пойдет прежде всего о LINQ to Objects , но в последующих материалах также будут затронуты и другие разновидности LINQ.

В чем же удобство LINQ? Посмотрим на простейшем примере. Выберем из массива строки, начинающиеся на определенную букву и отсортируем полученный список:

Теперь проведем те же действия с помощью LINQ:

Чтобы использовать функциональность LINQ, убедимся, что в файле подключено пространство имен System.LINQ .

Итак, код стал меньше и проще. В принципе все выражение можно было бы записать в одну строку: var selectedTeams = from t in teams where t.ToUpper().StartsWith(«Б») orderby t select t . Но для более понятной логической разбивки я поместил каждое отдельное подвыражение на отдельной строке.

Читайте также:  Как удалить rocketdock для windows

Простейшее определение запроса LINQ выглядит следующим образом:

Итак, что делает этот запрос LINQ? Выражение from t in teams проходит по всем элементам массива teams и определяет каждый элемент как t . Используя переменную t мы можем проводить над ней разные операции.

Несмотря на то, что мы не указываем тип переменной t , выражения LINQ являются строго типизированными. То есть среда автоматически распознает, что набор teams состоит из объектов string, поэтому переменная t будет рассматриваться в качестве строки.

Далее с помощью оператора where проводится фильтрация объектов, и если объект соответствует критерию (в данном случае начальная буква должна быть «Б»), то этот объект передается дальше.

Оператор orderby упорядочивает по возрастанию, то есть сортирует выбранные объекты.

Оператор select передает выбранные значения в результирующую выборку, которая возвращается LINQ-выражением.

В данном случае результатом выражения LINQ является объект IEnumerable . Нередко результирующая выборка определяется с помощью ключевого слова var , тогда компилятор на этапе компиляции сам выводит тип.

Преимуществом подобных запросов также является и то, что они интуитивно похожи на запросы языка SQL, хотя и имеют некоторые отличия.

Методы расширения LINQ

Кроме стандартного синтаксиса from .. in .. select для создания запроса LINQ мы можем применять специальные методы расширения, которые определены для интерфейса IEnumerable . Как правило, эти методы реализуют ту же функциональность, что и операторы LINQ типа where или orderby .

Запрос teams.Where(t=>t.ToUpper().StartsWith(«Б»)).OrderBy(t => t) будет аналогичен предыдущему. Он состоит из цепочки методов Where и OrderBy. В качестве аргумента эти методы принимают делегат или лямбда-выражение.

Не каждый метод расширения имеет аналог среди операторов LINQ, но в этом случае можно сочетать оба подхода. Например, используем стандартный синтаксис linq и метод расширения Count(), возвращающий количество элементов в выборке:

Список используемых методов расширения LINQ

Select : определяет проекцию выбранных значений

Where : определяет фильтр выборки

OrderBy : упорядочивает элементы по возрастанию

OrderByDescending : упорядочивает элементы по убыванию

ThenBy : задает дополнительные критерии для упорядочивания элементов возрастанию

ThenByDescending : задает дополнительные критерии для упорядочивания элементов по убыванию

Join : соединяет две коллекции по определенному признаку

GroupBy : группирует элементы по ключу

ToLookup : группирует элементы по ключу, при этом все элементы добавляются в словарь

GroupJoin : выполняет одновременно соединение коллекций и группировку элементов по ключу

Reverse : располагает элементы в обратном порядке

All : определяет, все ли элементы коллекции удовлятворяют определенному условию

Any : определяет, удовлетворяет хотя бы один элемент коллекции определенному условию

Contains : определяет, содержит ли коллекция определенный элемент

Distinct : удаляет дублирующиеся элементы из коллекции

Except : возвращает разность двух коллекцию, то есть те элементы, которые создаются только в одной коллекции

Union : объединяет две однородные коллекции

Intersect : возвращает пересечение двух коллекций, то есть те элементы, которые встречаются в обоих коллекциях

Count : подсчитывает количество элементов коллекции, которые удовлетворяют определенному условию

Sum : подсчитывает сумму числовых значений в коллекции

Average : подсчитывает cреднее значение числовых значений в коллекции

Min : находит минимальное значение

Max : находит максимальное значение

Take : выбирает определенное количество элементов

Skip : пропускает определенное количество элементов

TakeWhile : возвращает цепочку элементов последовательности, до тех пор, пока условие истинно

SkipWhile : пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы

Concat : объединяет две коллекции

Zip : объединяет две коллекции в соответствии с определенным условием

First : выбирает первый элемент коллекции

FirstOrDefault : выбирает первый элемент коллекции или возвращает значение по умолчанию

Single : выбирает единственный элемент коллекции, если коллекция содердит больше или меньше одного элемента, то генерируется исключение

SingleOrDefault : выбирает первый элемент коллекции или возвращает значение по умолчанию

ElementAt : выбирает элемент последовательности по определенному индексу

ElementAtOrDefault : выбирает элемент коллекции по определенному индексу или возвращает значение по умолчанию, если индекс вне допустимого диапазона

Last : выбирает последний элемент коллекции

LastOrDefault : выбирает последний элемент коллекции или возвращает значение по умолчанию

Введение в запросы LINQ (C#) Introduction to LINQ Queries (C#)

Запрос представляет собой выражение, извлекающее данные из источника данных. A query is an expression that retrieves data from a data source. Запросы обычно выражаются на специализированном языке запросов. Queries are usually expressed in a specialized query language. Со временем для различных типов источников данных, например SQL для реляционных баз данных и XQuery для XML, были разработаны разные языки. Different languages have been developed over time for the various types of data sources, for example SQL for relational databases and XQuery for XML. Поэтому разработчикам приходится учить новый язык запросов для каждого типа источника данных или формата данных, для которых они должны обеспечить поддержку. Therefore, developers have had to learn a new query language for each type of data source or data format that they must support. LINQ упрощает ситуацию, реализуя согласованную модель работы с данными для различных типов источников и форматов данных. LINQ simplifies this situation by offering a consistent model for working with data across various kinds of data sources and formats. В запросе LINQ вы всегда работаете с объектами. In a LINQ query, you are always working with objects. Вы используете одинаковые базовые шаблоны кода для запроса и преобразования данных в XML-документы, базы данных SQL, наборы данных ADO.NET, коллекции .NET и любые другие форматы, для которых доступен поставщик LINQ. You use the same basic coding patterns to query and transform data in XML documents, SQL databases, ADO.NET Datasets, .NET collections, and any other format for which a LINQ provider is available.

Читайте также:  Когда будет обновление lumia 1520 до windows 10

Три составляющие операции запроса Three Parts of a Query Operation

Все операции запросов LINQ состоят из трех отдельных действий: All LINQ query operations consist of three distinct actions:

получение источника данных; Obtain the data source.

создание запроса; Create the query.

выполнение запроса. Execute the query.

В следующем примере показано, как эти три части операции запроса выражаются в исходном коде. The following example shows how the three parts of a query operation are expressed in source code. В этом примере для удобства используется массив целых чисел в качестве источника данных. Тем не менее те же принципы применимы к другим источникам данных. The example uses an integer array as a data source for convenience; however, the same concepts apply to other data sources also. Остальные процедуры этого раздела содержат ссылки на этот пример. This example is referred to throughout the rest of this topic.

На следующем рисунке показана полная операция запроса. The following illustration shows the complete query operation. Выполнение запроса в LINQ отличается от самого запроса. In LINQ, the execution of the query is distinct from the query itself. Иными словами, данные не извлекаются путем создания переменной запроса. In other words, you have not retrieved any data just by creating a query variable.

Источник данных The Data Source

Так как источник данных в предыдущем примере является массивом, он неявно поддерживает универсальный интерфейс IEnumerable . In the previous example, because the data source is an array, it implicitly supports the generic IEnumerable interface. Это значит, что его можно запросить с помощью LINQ. This fact means it can be queried with LINQ. Запрос выполняется в операторе foreach , и для foreach требуется IEnumerable или IEnumerable . A query is executed in a foreach statement, and foreach requires IEnumerable or IEnumerable . Типы, которые поддерживают IEnumerable или производный интерфейс, например универсальный интерфейс IQueryable , называются запрашиваемыми типами. Types that support IEnumerable or a derived interface such as the generic IQueryable are called queryable types.

Запрашиваемый тип не требует внесения изменений или специальной обработки, чтобы служить источником данных LINQ. A queryable type requires no modification or special treatment to serve as a LINQ data source. Если источник данных не находится в памяти в качестве запрашиваемого типа, поставщик LINQ должен представить его как таковой. If the source data is not already in memory as a queryable type, the LINQ provider must represent it as such. Например, LINQ to XML LINQ to XML загружает XML-документ в запрашиваемый тип XElement: For example, LINQ to XML LINQ to XML loads an XML document into a queryable XElement type:

В LINQ to SQL LINQ to SQL сначала необходимо создать объектно-реляционное сопоставление во время разработки вручную либо с помощью инструментов LINQ to SQL в Visual Studio. With LINQ to SQL LINQ to SQL , you first create an object-relational mapping at design time either manually or by using the LINQ to SQL Tools in Visual Studio. Вы создаете запросы к объектам, а LINQ to SQL LINQ to SQL во время выполнения обрабатывает взаимодействие с базой данных. You write your queries against the objects, and at run-time LINQ to SQL LINQ to SQL handles the communication with the database. В следующем примере Customers представляет собой определенную таблицу в базе данных, а тип результата запроса (IQueryable ) является производным от IEnumerable . In the following example, Customers represents a specific table in the database, and the type of the query result, IQueryable , derives from IEnumerable .

Дополнительные сведения о способах создания определенных типов источников данных см. в документации для различных поставщиков LINQ. For more information about how to create specific types of data sources, see the documentation for the various LINQ providers. Но общее правило очень простое: источником данных LINQ является любой объект, который поддерживает универсальный интерфейс IEnumerable или интерфейс, наследуемый от него. However, the basic rule is very simple: a LINQ data source is any object that supports the generic IEnumerable interface, or an interface that inherits from it.

Такие типы как ArrayList, которые поддерживают неуниверсальный интерфейс IEnumerable, также можно использовать в качестве источника данных LINQ. Types such as ArrayList that support the non-generic IEnumerable interface can also be used as a LINQ data source. Дополнительные сведения см. в разделе Практическое руководство. Выполнение запроса к ArrayList с помощью LINQ (C#). For more information, see How to query an ArrayList with LINQ (C#).

Запрос The Query

Запрос указывает, какую информацию нужно извлечь из источника или источников данных. The query specifies what information to retrieve from the data source or sources. Дополнительно в запросе можно указать, как следует сортировать, группировать и формировать возвращаемую информацию. Optionally, a query also specifies how that information should be sorted, grouped, and shaped before it is returned. Запрос хранится в переменной запроса и инициализируется выражением запроса. A query is stored in a query variable and initialized with a query expression. Чтобы упростить написание запросов, в C# был представлен новый синтаксис запроса. To make it easier to write queries, C# has introduced new query syntax.

Читайте также:  Как диагностика ssd linux

В предыдущем примере запрос возвращает все четные числа из массива целых чисел. The query in the previous example returns all the even numbers from the integer array. Выражение запроса содержит три предложения: from , where и select . The query expression contains three clauses: from , where and select . (Если вы знакомы с SQL, то должны были заметить, что порядок предложений противоположен порядку в SQL.) Предложение from указывает источник данных, предложение where применяет фильтр, а предложение select задает тип возвращаемых элементов. (If you are familiar with SQL, you will have noticed that the ordering of the clauses is reversed from the order in SQL.) The from clause specifies the data source, the where clause applies the filter, and the select clause specifies the type of the returned elements. Эти и другие предложения запросов подробно описываются в разделе LINQ. These and the other query clauses are discussed in detail in the Language Integrated Query (LINQ) section. А сейчас важно то, что в LINQ сама переменная запроса не выполняет никаких действий и не возвращает никаких данных. For now, the important point is that in LINQ, the query variable itself takes no action and returns no data. Она просто хранит сведения, необходимые для предоставления результатов при выполнении запроса на более позднем этапе. It just stores the information that is required to produce the results when the query is executed at some later point. Дополнительные сведения о принципах конструирования запросов см. в разделе Общие сведения о стандартных операторах запросов (C#). For more information about how queries are constructed behind the scenes, see Standard Query Operators Overview (C#).

Запросы могут также выражаться с помощью синтаксиса методов. Queries can also be expressed by using method syntax. Дополнительные сведения см. в разделе Синтаксис запросов и синтаксис методов в LINQ. For more information, see Query Syntax and Method Syntax in LINQ.

Выполнение запроса Query Execution

Отложенное выполнение Deferred Execution

Как уже говорилось ранее, сама переменная запроса хранит команды запроса. As stated previously, the query variable itself only stores the query commands. Фактическое выполнение запроса откладывается до тех пор, пока переменная запроса не будет обработана в операторе foreach . The actual execution of the query is deferred until you iterate over the query variable in a foreach statement. Эта концепция называется отложенным выполнением и демонстрируется в следующем примере: This concept is referred to as deferred execution and is demonstrated in the following example:

Оператор foreach также является частью кода, в которой извлекаются результаты запроса. The foreach statement is also where the query results are retrieved. Например, в предыдущем запросе переменная итерации num содержит каждое значение (по одному за раз) в возвращенной последовательности. For example, in the previous query, the iteration variable num holds each value (one at a time) in the returned sequence.

Поскольку сама переменная запроса никогда не содержит результаты запроса, вы можете выполнять ее так часто, как это необходимо. Because the query variable itself never holds the query results, you can execute it as often as you like. Например, может иметься база данных, постоянно обновляемая отдельным приложением. For example, you may have a database that is being updated continually by a separate application. В приложении можно создать один запрос, получающий самые последние данные, и регулярно выполнять его с некоторым интервалом, каждый раз получая разные результаты. In your application, you could create one query that retrieves the latest data, and you could execute it repeatedly at some interval to retrieve different results every time.

Принудительное немедленное выполнение Forcing Immediate Execution

Запросы, выполняющие статистические функции для диапазона исходных элементов, сначала должны выполнить итерацию по этим элементам. Queries that perform aggregation functions over a range of source elements must first iterate over those elements. Примерами таких запросов являются Count , Max , Average и First . Examples of such queries are Count , Max , Average , and First . Они выполняются без явного оператора foreach , поскольку сам запрос должен использовать foreach для возвращения результата. These execute without an explicit foreach statement because the query itself must use foreach in order to return a result. Обратите внимание, что такие типы запросов возвращают одно значение, а не коллекцию IEnumerable . Note also that these types of queries return a single value, not an IEnumerable collection. Следующий запрос возвращает количество четных чисел в исходном массиве: The following query returns a count of the even numbers in the source array:

Чтобы принудительно вызвать немедленное выполнение любого запроса и кэшировать его результаты, вы можете вызвать методы ToList или ToArray. To force immediate execution of any query and cache its results, you can call the ToList or ToArray methods.

Принудительно вызвать выполнение также можно, поместив цикл foreach сразу после выражения запроса. You can also force execution by putting the foreach loop immediately after the query expression. При этом путем вызова ToList или ToArray можно также кэшировать все данные в одном объекте коллекции. However, by calling ToList or ToArray you also cache all the data in a single collection object.

Оцените статью