This article has multiple issues. Please helpimprove it or discuss these issues on thetalk page.(Learn how and when to remove these messages) (Learn how and when to remove this message)
|
| Language Integrated Query | |
|---|---|
| Designed by | Microsoft Corporation |
| Developer | Microsoft Corporation |
| Typing discipline | Strongly typed |
| Website | https://learn.microsoft.com/en-us/dotnet/standard/linq/ |
| Majorimplementations | |
| .NET languages (C#,F#,VB.NET) | |
| Influenced by | |
| SQL,Haskell | |
Language Integrated Query (LINQ, pronounced "link") is aMicrosoft.NET Framework component that adds native dataquerying capabilities to.NET languages, originally released as a major part of.NET Framework 3.5 in 2007.
LINQ extends the language by the addition of queryexpressions, which are akin toSQL statements, and can be used to conveniently extract and process data fromarrays, enumerableclasses,XML documents,relational databases, and third-party data sources. Other uses, which utilize query expressions as a general framework for readably composing arbitrary computations, include the construction of event handlers[1] ormonadicparsers.[2] It also defines a set of method names (calledstandard query operators, orstandard sequence operators), along with translation rules used by the compiler to translate query syntax expressions into expressions usingfluent-style (called method syntax by Microsoft) with these method names,lambda expressions andanonymous types.
In what follows, the descriptions of the operators are based on the application of working with collections. Many of the operators take other functions as arguments. These functions may be supplied in the form of a named method or anonymous function.
The set of queryoperators defined by LINQ is exposed to the user as the Standard Query Operator (SQO)API. The query operators supported by the API are:[3]
These operators optionally take a function that retrieves a certain numeric value from each element in the collection and uses it to find the sum, minimum, maximum or average values of all the elements in the collection, respectively. Overloaded versions take no function and act as if the identity is given as the lambda.
A generalized Sum / Min / Max. This operator takes a function that specifies how two values are combined to form an intermediate or the final result. Optionally, a starting value can be supplied, enabling the result type of the aggregation to be arbitrary. Furthermore, a finalization function, taking the aggregation result to yet another value, can be supplied. This implement theFold higher-order function.
IGrouping<Key, Values> objects, for each distinct key value. TheIGrouping objects can then be used to enumerate all the objects for a particular key value.The standard query operator API also specifies certain operators that convert a collection into another type:[3]
IEnumerable<T>.[4]IQueryable<T>.T[] from the collection.List<T> from the collection.Dictionary<K, T> from the collection, indexed by the key K. A user supplied projection function extracts a key from each element.Lookup<K, T> from the collection, indexed by the key K. A user supplied projection function extracts a key from each element.IEnumerable collection to one ofIEnumerable<T> by casting each element to typeT. Alternately converts a genericIEnumerable<T> to another genericIEnumerable<R> by casting each element from typeT to typeR. Throws an exception in any element cannot be cast to the indicated type.IEnumerable collection to one ofIEnumerable<T>. Alternately converts a genericIEnumerable<T> to another genericIEnumerable<R> by attempting to cast each element from typeT to typeR. In both cases, only the subset of elements successfully cast to the target type are included. No exceptions are thrown.While LINQ is primarily implemented as alibrary for .NET Framework 3.5, it also defines optional language extensions that make queries a first-classlanguage construct and providesyntactic sugar for writing queries. These language extensions have initially been implemented inC# 3.0,[5]: 75 VB 9.0,F#[6] andOxygene, with other languages likeNemerle having announced preliminary support. The language extensions include:[7]
var keyword. In VB9.0, theDim keyword without type declaration accomplishes the same. Such objects are stillstrongly typed; for these objects the compiler infers the types of variables viatype inference, which allows the results of the queries to be specified and defined without declaring the type of the intermediate variables.For example, in the query to select all the objects in a collection withSomeProperty less than 10,
IEnumerable<MyObject>SomeCollection=/* something here */IEnumerable<MyObject>results=fromcinSomeCollectionwherec.SomeProperty<10selectnew{c.SomeProperty,c.OtherProperty};foreach(MyObjectresultinresults){Console.WriteLine(result);}
the types of variablesresult,c andresults all are inferred by the compiler in accordance to the signatures of the methods eventually used. The basis for choosing the methods is formed by the query expression-free translation result
IEnumerble<MyObject>results=SomeCollection.Where(c=>c.SomeProperty<10).Select(c=>new{c.SomeProperty,c.OtherProperty});results.ForEach(x=>{Console.WriteLine(x.ToString());})
The C#3.0 specification defines a Query Expression Pattern along with translation rules from a LINQ expression to an expression in a subset of C# 3.0 without LINQ expressions. The translation thus defined is actually un-typed, which, in addition to lambda expressions being interpretable as either delegates or expression trees, allows for a great degree of flexibility for libraries wishing to expose parts of their interface as LINQ expression clauses. For example,LINQ to Objects works onIEnumerable<T>s and with delegates, whereasLINQ to SQL makes use of the expression trees.
The expression trees are at the core of the LINQ extensibility mechanism, by which LINQ can be adapted for many data sources. The expression trees are handed over to LINQ Providers, which are data source-specific implementations that adapt the LINQ queries to be used with the data source. If they choose so, the LINQ Providers analyze the expression trees contained in a query in order to generate essential pieces needed for the execution of a query. This can be SQL fragments or any other completely different representation of code as further manipulatable data.LINQ comes with LINQ Providers for in-memory object collections,Microsoft SQL Server databases,ADO.NET datasets and XML documents. These different providers define the different flavors of LINQ:
The LINQ to Objects provider is used for in-memory collections, using the local query execution engine of LINQ. The code generated by this provider refers to the implementation of the standard query operators as defined on theSequence pattern and allowsIEnumerable<T> collections to be queried locally. Current implementation of LINQ to Objects perform interface implementation checks to allow for fast membership tests, counts, and indexed lookup operations when they are supported by the runtime type of the IEnumerable.[8][9][10]
The LINQ to XML provider converts an XML document to a collection ofXElement objects, which are then queried against using the local execution engine that is provided as a part of the implementation of the standard query operator.[11]
The LINQ to SQL provider allows LINQ to be used to queryMicrosoft SQL Server databases, includingSQL Server Compact databases. Since SQL Server data may reside on a remote server, and because SQL Server has its own query engine, LINQ to SQL does not use the query engine of LINQ. Instead, it converts a LINQ query to aSQL query that is then sent to SQL Server for processing.[12] However, since SQL Server stores the data asrelational data and LINQ works with data encapsulated in objects, the two representations must bemapped to one another. For this reason, LINQ to SQL also defines a mapping framework. The mapping is done by defining classes that correspond to the tables in the database, and containing all or a subset of the columns in the table as data members.[13] The correspondence, along with otherrelational model attributes such asprimary keys, are specified using LINQ to SQL-definedattributes. For example,
[Table(Name="Customers")]publicclassCustomer{[Column(IsPrimaryKey = true)]publicintCustID;[Column]publicstringCustName;}
This class definition maps to a table namedCustomers and the two data members correspond to two columns. The classes must be defined before LINQ to SQL can be used.Visual Studio 2008 includes a mapping designer that can be used to create the mapping between the data schemas in the object as well as the relational domain. It can automatically create the corresponding classes from adatabase schema, as well as allow manual editing to create a different view by using only a subset of the tables or columns in a table.[13]
The mapping is implemented by theDataContext that takes a connection string to the server, and can be used to generate aTable<T> where T is the type to which the database table will be mapped. TheTable<T> encapsulates the data in the table, and implements theIQueryable<T> interface, so that the expression tree is created, which the LINQ to SQL provider handles. It converts the query intoT-SQL and retrieves the result set from the database server. Since the processing happens at the database server, local methods, which are not defined as a part of the lambda expressions representing the predicates, cannot be used. However, it can use thestored procedures on the server. Any changes to the result set are tracked and can be submitted back to the database server.[13]
Since the LINQ to SQL provider (above) works only withMicrosoft SQL Server databases, in order to support any generic database, LINQ also includes the LINQ to DataSets. It uses ADO.NET to handle the communication with the database. Once the data is in ADO.NET Datasets, LINQ to DataSets execute queries against these datasets.[14]
Parts of this article (those related to Performance) need to beupdated. The reason given is: The source is old and now performs better than before. Please help update this article to reflect recent events or newly available information.(November 2021) |
Non-professional users may struggle with subtleties in theLINQ to Objects features and syntax. Naive LINQ implementation patterns can lead to a catastrophic degradation of performance.[15][16]
LINQ to XML andLINQ to SQL performance compared to ADO.NET depends on the use case.[17][18]
Version 4 of the .NET framework includesPLINQ, orParallel LINQ, aparallel execution engine for LINQ queries. It defines theParallelQuery<T> class. Any implementation of theIEnumerable<T> interface can take advantage of the PLINQ engine by calling theAsParallel<T>(thisIEnumerable<T>) extension method defined by the ParallelEnumerable class in the System.Linq namespace of the .NET framework.[19] The PLINQ engine can execute parts of a query concurrently on multiple threads, providing faster results.[20]
Many of the concepts that LINQ introduced were originally tested in Microsoft'sCω research project, formerly known by thecodenamesX# (X Sharp) andXen. It was renamed to Cω afterPolyphonic C# (another research language based onjoin calculus principles) was integrated into it.
Cω attempts to make datastores (such asdatabases andXML documents) accessible with the same ease andtype safety as traditional types likestrings andarrays. Many of these ideas were inherited from an earlier incubation project within the WebData XML team called X# and Xen. Cω also includes new constructs to supportconcurrent programming; these features were largely derived from the earlier Polyphonic C# project.[21]
First available in 2004 as a compiler preview, Cω's features were subsequently used by Microsoft in the creation of the LINQ features released in 2007 in .NET version 3.5[22] The concurrency constructs have also been released in a slightly modified form as a library, namedJoins Concurrency Library, forC# and other .NET languages byMicrosoft Research.[23]
Ports of LINQ exist forPHP (PHPLinqArchived 2018-01-19 at theWayback Machine),JavaScript (linq.js),TypeScript (linq.ts), andActionScript (ActionLinqArchived 2018-12-25 at theWayback Machine), and C++ (CXXIter), although none are strictly equivalent to LINQ in the .NET inspired languages C#, F# and VB.NET (where it is a part of the language, not an external library, and where it often addresses a wider range of needs).[citation needed]
While it is true that LINQ is powerful and very efficient, large sets of data can still cause unexpected performance problems
When calling a query multiple times with Entity Framework the recommended approach is to use compiled LINQ queries. Compiling a query results in a performance hit the first time you use the query but subsequent calls execute much faster