Note pour C# in a nutshell Ch 7

LINQ: Language Integrated Query, isa set of language and framework features for writing structured type-safequeries over local object collections and remote data sources, introduced in C#3.0 FM 3.5.

LINQ enables to query any collectionimplementing IEnumerable<T>. LINQ offers the benefits of bothcompile-time type checking and dynamic query composition.

All core types are defined in theSystem.Linq and System.Linq.Expressions namespaces.

Getting Started

The basic units of data in LINQ aresequences and elements.

Sequence: any object that implementsIEnumerable<T>

Element: each item in the sequence.

Local sequence: represent a localcollection of objects in memory.

Query: an expression that transformssequences with query operators

Queries that operates over localsequences are called local queries or LINQ-to-objects queries

Query operator: a method thattransforms a sequence. A typical query operator accepts an input sequence andemits a transformed output sequence. Standard query operator: static extensionmethods

Most query operators accept a lambdaexpression as an argument. The lambda expression helps guide and shape thequery.

Fluent Syntax

Fluent syntax is the most flexibleand fundamental.

Chaining Query Operators

Data flows from left to rightthrough the chain of operators.

A query operator never alters theinput sequence, it returns a new sequence. The output sequence of one operatoris the input sequence of the next.

Withoutextension methods, the query loses its fluency:

IEnumerable<string> query = Enumerable.Select (Enumerable.Where( names, n => n.Contains(“a”) ), n => n.ToUpper() );

Composing Lambda Expressions

An expression returning a bool valueis called a predicate.

A lambda expression in a queryoperator always works on individual elements in the input sequence, not thesequence as a whole.

Then standard query operatorsutilize generic Func delegates. Func is a family of general-purpose genericdelegates in System.Linq, defined with the following intent: The type argumentsin Func appear in the same order they do in lambda expressions.  

Func<TSource, TResult>:TSource => TResult

The compiler infers the type ofTResult from the return value of the lambda expression. For Where, input andoutput elements are of the same type.

Natural Ordering

The original ordering of elementswithin an input sequence is significant in LINQ. Some query operators rely onthis behavior, such as Take, Skip and Reverse.

The Take operator outputs the firstx elements, discarding the rest.

The Skip operator ignores the firstx elements and outputs the rest.

LINQ preserves the ordering ofelements in the input sequence wherever possible.

Other Operators

Not all query return a sequence: Theymust appear as the last operators on the result, they don’t return acollection. Element operators First, Last, ElementAt extract one element;Aggregation operators Count, Min return a scalar value, usually of numerictype; Quantifiers Contains, Any return a bool value.

Some query operators accept twoinput sequences: Concat, Union (with duplicates removed)

Query Expressions

Query expressions: based on listcomprehensions from functional programming languages, not on SQL.

Query expressions always start witha from clause and ends with either a select or group clause. The from clausedeclares a range variable, rather like foreach.

The compiler processes a queryexpression by translating it into fluent syntax. Anything written in querysyntax can be written in fluent syntax.

Query expressions cannot compileunless you import a namespace, or write an instance method for every queryoperator.

Range Variables

Rang variable: the identifierimmediately following the from keyword syntax, refers to the current element inthe sequence that the operation is to be performed on.

 Query expressions also let you introduce newrange variables via let, into or an additional from clause.

Query Syntax vs. SQL Syntax

They are very different. A LINQquery is a C# expression, follows standard C# rules: can’t use a variablebefore declaration; dataflow left to right; a conveyor belt or pipeline ofoperators that accept and emit ordered sequences.

Query Syntax vs. Fluent Syntax

Query and fluent syntax each haveadvantages.

Query syntax for queries that:

­  Alet clause for introducing a new variable alongside the range variable

­  SelectMany,Join or GroupJoin, followed by an outer range variable reference

Fluent syntax:

­  Queriesthat comprise a single operator

­  Anyoperator except: Where, Select, SelectMany, OrderBy, ThenBy, OrderByDescending,ThenByDescending, GroupBy, Join, GroupJoin require fluent syntax, at least inpart. They have no keyword in query syntax.

Mixed Syntax Queries

If a query operator has noquery-syntax support, you can mix query syntax and fluent syntax. The onlyrestriction is that each query-syntax component must be complete(from…select/group).

Deferred Execution

An important feature of most queryoperators is that they execute not when constructed, but when enumerated – whenMoveNext is called (foreach). This is called deferred or lazy execution.

All standard query operators providedeferred execution, except: Operators that return a single element or scalarvalue, such as First or Count; Conversion operators as ToArray, ToList,ToDictionary, ToLookup. These operators cause immediate query execution.

Deferred execution is importantbecause it decouples query construction from query execution, allowingconstructing a query in several steps.

Reevaluation

A deferred execution query isreevaluated when re-enumerate. We can defeat reevaluation by calling aconversion operator, such as ToArray or ToList. ToArray copies the output of aquery to an array, ToList to a generic List<>.

Captured Variables

Deferred execution has a sinistereffect. If the query’s lambda expressions referencelocal variables, these variables are captured variables. Captured variables are evaluated when the delegate isactually invoked (调用), not when the variables were captured. If you later change their value, thequery changes as well.

Don’tunderstand!!!!!

How Deferred Execution Works

Query operators provide deferredexecution by returning decorator sequences. A decorator sequence has no backingstructure of its own to store elements. Instead, it wraps another sequence thatyou supply at runtime, to which it maintains a permanent dependency. Wheneveryou request data from a decorator, it in turn must request data from thewrapped input sequence.

Calling Where merely constructs thedecorator wrapper sequence, holding a reference to the input sequence. Theinput sequence is enumerated only when the decorator is enumerated.

To write own query operator is justimplementing a decorator sequence.

Chaining Decorators

Chaining query operators create alayering of decorators. Each query operator instantiates a new decorator thatwraps the previous sequence. The model of chaining decorators is fully constructedprior to any enumeration.

Adding ToList onto the end of thequery would cause the preceding operators to execute right away.

How Queries Are Executed

LINQ query is a lazy productionline, where the conveyor belts roll elements only upon demand. Constructing aquery constructs a production line, with everything in place but with nothingrolling. Then when the consumer requests an element (enumerating), the rightmostconveyor belt activates; this in turn triggers the other to roll, when inputsequence elements are needed. LINQ follows a demand-driven pull model.

Subqueries

A subquery is a query containedwithin another query’s lambda expression. The rules for subqueries are aconsequence of the rules for lambda expressions and the behavior of queryoperators in general.

A subquery is privately scoped tothe enclosing expression and is able to reference the outer lambda argument (orrange variable in a query expression). 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值