Linq 简明教程
LINQ - Overview
由于缺少明确的路径,并需要精通 SQL、Web 服务、XQuery 等多项技术,世界各地的开发人员在查询数据时总会遇到问题。
Developers across the world have always encountered problems in querying data because of the lack of a defined path and need to master a multiple of technologies like SQL, Web Services, XQuery, etc.
LINQ(语言集成查询)由 Anders Hejlsberg 设计,在 Visual Studio 2008 中引入,允许编写查询,即使不知道 SQL、XML 等查询语言。可为不同数据类型编写 LINQ 查询。
Introduced in Visual Studio 2008 and designed by Anders Hejlsberg, LINQ (Language Integrated Query) allows writing queries even without the knowledge of query languages like SQL, XML etc. LINQ queries can be written for diverse data types.
Example of a LINQ query
C
using System;
using System.Linq;
class Program {
static void Main() {
string[] words = {"hello", "wonderful", "LINQ", "beautiful", "world"};
//Get only short words
var shortWords = from word in words where word.Length <= 5 select word;
//Print each word out
foreach (var word in shortWords) {
Console.WriteLine(word);
}
Console.ReadLine();
}
}
VB
Module Module1
Sub Main()
Dim words As String() = {"hello", "wonderful", "LINQ", "beautiful", "world"}
' Get only short words
Dim shortWords = From word In words _ Where word.Length <= 5 _ Select word
' Print each word out.
For Each word In shortWords
Console.WriteLine(word)
Next
Console.ReadLine()
End Sub
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
hello
LINQ
world
Syntax of LINQ
LINQ 的语法有两种。它们如下所示。
There are two syntaxes of LINQ. These are the following ones.
Types of LINQ
LINQ 的类型概述如下。
The types of LINQ are mentioned below in brief.
-
LINQ to Objects
-
LINQ to XML(XLINQ)
-
LINQ to DataSet
-
LINQ to SQL (DLINQ)
-
LINQ to Entities
除了上述类型之外,还有一个名为 PLINQ 的 LINQ 类型,它是 Microsoft 提供的并行 LINQ。
Apart from the above, there is also a LINQ type named PLINQ which is Microsoft’s parallel LINQ.
LINQ Architecture in .NET
LINQ 具有一个 3 层架构,其中最上层由语言扩展组成,最底层由通常实现 IEnumerable 或 IQueryable 通用接口的对象(数据源)组成。该架构如下所示。
LINQ has a 3-layered architecture in which the uppermost layer consists of the language extensions and the bottom layer consists of data sources that are typically objects implementing IEnumerable <T> or IQueryable <T> generic interfaces. The architecture is shown below.
Query Expressions
查询表达式只不过是一个 LINQ 查询,它以类似于 SQL 的形式表示,带有 Select、Where 和 OrderBy 等查询运算符。查询表达式通常以关键词“From”开头。
Query expression is nothing but a LINQ query, expressed in a form similar to that of SQL with query operators like Select, Where and OrderBy. Query expressions usually start with the keyword "From".
要访问标准 LINQ 查询运算符,应默认导入命名空间 System.Query。这些表达式写在声明式查询语法内,该语法是 C# 3.0 的。
To access standard LINQ query operators, the namespace System.Query should be imported by default. These expressions are written within a declarative query syntax which was C# 3.0.
下面是一个示例,展示了一个完整的查询操作,该操作包括数据源创建、查询表达式定义和查询执行。
Below is an example to show a complete query operation which consists of data source creation, query expression definition and query execution.
C
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Operators {
class LINQQueryExpressions {
static void Main() {
// Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 };
// Define the query expression.
IEnumerable<int> scoreQuery = from score in scores where score > 80 select score;
// Execute the query.
foreach (int i in scoreQuery) {
Console.Write(i + " ");
}
Console.ReadLine();
}
}
}
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
97 92 81
Extension Methods
使用 .NET 3.5 引入,仅在静态类中声明扩展方法,并允许将自定义方法包含到对象中,以执行一些精确的查询操作,而无需成为该类的实际成员。这些方法还可以重载。
Introduced with .NET 3.5, Extension methods are declared in static classes only and allow inclusion of custom methods to objects to perform some precise query operations to extend a class without being an actual member of that class. These can be overloaded also.
简而言之,扩展方法用于将查询表达式转换为传统方法调用(面向对象)。
In a nutshell, extension methods are used to translate query expressions into traditional method calls (object-oriented).
Difference between LINQ and Stored Procedure
LINQ 和存储过程之间有很多差异。这些差异如下所述。
There is an array of differences existing between LINQ and Stored procedures. These differences are mentioned below.
-
Stored procedures are much faster than a LINQ query as they follow an expected execution plan.
-
It is easy to avoid run-time errors while executing a LINQ query than in comparison to a stored procedure as the former has Visual Studio’s Intellisense support as well as full-type checking during compile-time.
-
LINQ allows debugging by making use of .NET debugger which is not in case of stored procedures.
-
LINQ offers support for multiple databases in contrast to stored procedures, where it is essential to re-write the code for diverse types of databases.
-
Deployment of LINQ based solution is easy and simple in comparison to deployment of a set of stored procedures.
Need For LINQ
在 LINQ 之前,有必要学习 C#、SQL 和将两者结合在一起形成完整应用程序的各种 API。由于这些数据源和编程语言存在阻抗不匹配,因此需要简短的编码。
Prior to LINQ, it was essential to learn C#, SQL, and various APIs that bind together the both to form a complete application. Since, these data sources and programming languages face an impedance mismatch; a need of short coding is felt.
下面是一个示例,说明在 LINQ 出现之前,开发人员在查询数据时使用了多少种不同的技术。
Below is an example of how many diverse techniques were used by the developers while querying a data before the advent of LINQ.
SqlConnection sqlConnection = new SqlConnection(connectString);
SqlConnection.Open();
System.Data.SqlClient.SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "Select * from Customer";
return sqlCommand.ExecuteReader (CommandBehavior.CloseConnection)
有趣的是,在这些特色的代码行中,查询仅由最后两行定义。使用 LINQ,相同的 data 查询可以用可读的彩色彩色形式编写,如下所示,而且时间非常短。
Interestingly, out of the featured code lines, query gets defined only by the last two. Using LINQ, the same data query can be written in a readable color-coded form like the following one mentioned below that too in a very less time.
Northwind db = new Northwind(@"C:\Data\Northwnd.mdf");
var query = from c in db.Customers select c;
Advantages of LINQ
LINQ 提供了许多优势,其中首要优势是其强大的表达能力,使开发人员能够以声明方式表达。以下列出了 LINQ 的其他一些优势。
LINQ offers a host of advantages and among them the foremost is its powerful expressiveness which enables developers to express declaratively. Some of the other advantages of LINQ are given below.
-
LINQ offers syntax highlighting that proves helpful to find out mistakes during design time.
-
LINQ offers IntelliSense which means writing more accurate queries easily.
-
Writing codes is quite faster in LINQ and thus development time also gets reduced significantly.
-
LINQ makes easy debugging due to its integration in the C# language.
-
Viewing relationship between two tables is easy with LINQ due to its hierarchical feature and this enables composing queries joining multiple tables in less time.
-
LINQ allows usage of a single LINQ syntax while querying many diverse data sources and this is mainly because of its unitive foundation.
-
LINQ is extensible that means it is possible to use knowledge of LINQ to querying new data source types.
-
LINQ offers the facility of joining several data sources in a single query as well as breaking complex problems into a set of short queries easy to debug.
-
LINQ offers easy transformation for conversion of one data type to another like transforming SQL data to XML data.
LINQ - Environment Setup
在开始使用 LINQ 程序前,最好先了解 LINQ 环境的设置细节。LINQ 需要一个 .NET 框架,这是一种革命性的平台,可拥有各种应用程序。LINQ 查询既可以用 C# 也可用 Visual Basic 方便地编写。
Before starting with LINQ programs, it is best to first understand the nuances of setting up a LINQ environment. LINQ needs a .NET framework, a revolutionary platform to have a diverse kind of applications. A LINQ query can be written either in C# or Visual Basic conveniently.
微软通过 Visual Studio 为这两种语言 (即 C# 和 Visual Basic) 提供工具。我们的示例全部在 Visual Studio 2010 中编译和编写。但是,Visual Basic 2013 版也可以使用。它是最新版本,并且与 Visual Studio 2012 有许多相似之处。
Microsoft offers tools for both of these languages i.e. C# and Visual Basic by means of Visual Studio. Our examples are all compiled and written in Visual Studio 2010. However, Visual Basic 2013 edition is also available for use. It is the latest version and has many similarities with Visual Studio 2012.
Getting Visual Studio 2010 Installed on Windows 7
Visual Studio 可以从安装介质(如 DVD)中安装。成功在系统中安装 Visual Basic 2010 需要管理员凭据。在安装之前,必须断开系统中所有可移动 USB,否则安装可能会失败。以下列出了一些安装中必备的硬件要求。
Visual Studio can be installed either from an installation media like a DVD. Administrator credentials are required to install Visual Basic 2010 on your system successfully. It is vital to disconnect all removable USB from the system prior to installation otherwise the installation may get failed. Some of the hardware requirements essential to have for installation are the following ones.
Hardware Requirements
-
1.6 GHz or more
-
1 GB RAM
-
3 GB(Available hard-disk space)
-
5400 RPM hard-disk drive
-
DirectX 9 compatible video card
-
DVD-ROM drive
Installation Steps
Step 1 − 首先在插入 Visual Studio 2010 组件包 DVD 后,单击屏幕上弹出框中出现的 Install or run program from your media 。
Step 1 − First after inserting the DVD with Visual Studio 2010 Package, click on Install or run program from your media appearing in a pop-up box on the screen.
Step 2 − 现在屏幕上会出现 Visual Studio 的设置。选择 Install Microsoft Visual Studio 2010 。
Step 2 − Now set up for Visual Studio will appear on the screen. Choose Install Microsoft Visual Studio 2010.
Step 3 − 单击后,进程将启动,并且屏幕上会出现设置窗口。在完成安装组件的加载(这需要一些时间)后,单击 Next 按钮以移至下一步。
Step 3 − As soon as you will click, it the process will get initiated and a set up window will appear on your screen. After completion of loading of the installation components which will take some time, click on Next button to move to the next step.
Step 4 − 这是安装的最后一步,并且将出现一个开始页面,在其中只需选择“我已阅读并接受许可证条款”,然后单击 Next 按钮。
Step 4 − This is the last step of installation and a start page will appear in which simply choose "I have read and accept the license terms" and click on Next button.
Step 5 − 现在从屏幕上出现的选项页面中选择要安装的功能。您可以选择 Full 或 Custom 选项。如果您拥有的磁盘空间少于磁盘空间要求中显示所需的磁盘空间,请使用“自定义”。
Step 5 − Now select features to install from the options page appearing on your screen. You can either choose Full or Custom option. If you have less disk space than required shown in the disk space requirements, then go for Custom.
Step 6 − 选择“自定义”选项,以下窗口将出现。选择要安装的功能,然后单击 Update ,否则请转到步骤 7。但是,建议不要使用自定义选项,因为在将来,您可能需要您选择不安装的功能。
Step 6 − When you choose Custom option, the following window will appear. Select the features that you want to install and click Update or else go to step 7. However, it is recommended not to go with the custom option as in future, you may need the features you have chosen to not have.
Update − 不久后将显示一个弹出窗口,并且安装将开始,这可能需要很长时间。请记住,这是为了安装所有组件。
Step 7 − Soon a pop up window will be shown and the installation will start which may take a long time. Remember, this is for installing all the components.
Step 8 − 最后,您将可以在窗口中看到一条消息,提示安装已成功完成。单击 Finish 。
Step 8 − Finally, you will be able to view a message in a window that the installation has been completed successfully. Click Finish.
Writing C
-
Start Visual Studio 2010 Ultimate edition and choose File followed by New Project from the menu.
-
A new project dialog box will appear on your screen.
-
Now choose Visual C# as a category under installed templates and next choose Console Application template as shown in figure below.
-
Give a name to your project in the bottom name box and press OK.
-
The new project will appear in the Solution Explorer in the right-hand side of a new dialog box on your screen.
-
Now choose Program.cs from the Solution Explorer and you can view the code in the editor window which starts with ‘using System’.
-
Here you can start to code your following C# program.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HelloWorld {
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World")
Console.ReadKey();
}
}
}
-
Press F5 key and run your project. It is highly recommended to save the project by choosing File → Save All before running the project.
Writing VB Program using LINQ in Visual Studio 2010
-
Start Visual Studio 2010 Ultimate edition and choose File followed by New Project from the menu.
-
A new project dialog box will appear on your screen.
-
Now chose Visual Basic as a category under installed templates and next choose Console Application template.
-
Give a name to your project in the bottom name box and press OK.
-
You will get a screen with Module1.vb. Start writing your VB code here using LINQ.
Module Module1
Sub Main()
Console.WriteLine("Hello World")
Console.ReadLine()
End Sub
End Module
-
Press F5 key and run your project. It is highly recommended to save the project by choosing File → Save All before running the project.
当上面 C# 或 VB 代码 cimpiled 并运行时,它会产生以下结果 -
When the above code of C# or VB is cimpiled and run, it produces the following result −
Hello World
LINQ - Query Operators
形成查询模式的一组扩展方法被称为 LINQ 标准查询运算符。作为 LINQ 查询表达式的构建块,这些运算符提供了一系列查询功能,如筛选、排序、投影、聚合等。
A set of extension methods forming a query pattern is known as LINQ Standard Query Operators. As building blocks of LINQ query expressions, these operators offer a range of query capabilities like filtering, sorting, projection, aggregation, etc.
LINQ 标准查询运算符可以根据其功能归类为以下类。
LINQ standard query operators can be categorized into the following ones on the basis of their functionality.
-
Filtering Operators
-
Join Operators
-
Projection Operations
-
Sorting Operators
-
Grouping Operators
-
Conversions
-
Concatenation
-
Aggregation
-
Quantifier Operations
-
Partition Operations
-
Generation Operations
-
Set Operations
-
Equality
-
Element Operators
Filtering Operators
筛选是一种操作,用于限制结果集,以便它只有满足特定条件的选定元素。
Filtering is an operation to restrict the result set such that it has only selected elements satisfying a particular condition.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
where |
Filter values based on a predicate function |
where |
Where |
OfType |
Filter values based on their ability to be as a specified type |
Not Applicable |
Not Applicable |
Join Operators
联接是指以直接方式针对难以相互跟踪关系的数据源的操作。
Joining refers to an operation in which data sources with difficult to follow relationships with each other in a direct way are targeted.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Join |
The operator join two sequences on basis of matching keys |
join … in … on … equals … |
From x In …, y In … Where x.a = y.a |
GroupJoin |
Join two sequences and group the matching elements |
join … in … on … equals … into … |
Group Join … In … On … |
Projection Operations
投影是一种将对象转换成具有特定属性的全新形式的操作。
Projection is an operation in which an object is transformed into an altogether new form with only specific properties.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Select |
The operator projects values on basis of a transform function |
select |
Select |
SelectMany |
The operator project the sequences of values which are based on a transform function as well as flattens them into a single sequence |
Use multiple from clauses |
Use multiple From clauses |
Sorting Operators
排序操作允许基于单个或多个属性对序列的元素进行排序。
A sorting operation allows ordering the elements of a sequence on basis of a single or more attributes.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
OrderBy |
The operator sort values in an ascending order |
orderby |
Order By |
OrderByDescending |
The operator sort values in a descending order |
orderby … descending |
Order By … Descending |
ThenBy |
Executes a secondary sorting in an ascending order |
orderby …, … |
Order By …, … |
ThenByDescending |
Executes a secondary sorting in a descending order |
orderby …, … descending |
Order By …, … Descending |
Reverse |
Performs a reversal of the order of the elements in a collection |
Not Applicable |
Not Applicable |
Grouping Operators
运算符基于常用共享属性将数据放入到某些组中。
The operators put data into some groups based on a common shared attribute.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
GroupBy |
Organize a sequence of items in groups and return them as an IEnumerable collection of type IGrouping<key, element> |
group … by -or- group … by … into … |
Group … By … Into … |
ToLookup |
Execute a grouping operation in which a sequence of key pairs are returned |
Not Applicable |
Not Applicable |
Conversions
运算符会更改输入对象的类型,应用于各类应用程序中。
The operators change the type of input objects and are used in a diverse range of applications.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
AsEnumerable |
Returns the input typed as IEnumerable<T> |
Not Applicable |
Not Applicable |
AsQueryable |
A (generic) IEnumerable is converted to a (generic) IQueryable |
Not Applicable |
Not Applicable |
Cast |
Performs casting of elements of a collection to a specified type |
Use an explicitly typed range variable. Eg:from string str in words |
From … As … |
OfType |
Filters values on basis of their , depending on their capability to be cast to a particular type |
Not Applicable |
Not Applicable |
ToArray |
Forces query execution and does conversion of a collection to an array |
Not Applicable |
Not Applicable |
ToDictionary |
On basis of a key selector function set elements into a Dictionary<TKey, TValue> and forces execution of a LINQ query |
Not Applicable |
Not Applicable |
ToList |
Forces execution of a query by converting a collection to a List<T> |
Not Applicable |
Not Applicable |
ToLookup |
Forces execution of a query and put elements into a Lookup<TKey, TElement> on basis of a key selector function |
Not Applicable |
Not Applicable |
Concatenation
执行两个序列的连接,并且除不删除重复项这一事实外,在操作方面与 Union 运算符很相似。
Performs concatenation of two sequences and is quite similar to the Union operator in terms of its operation except of the fact that this does not remove duplicates.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Concat |
Two sequences are concatenated for the formation of a single one sequence. |
Not Applicable |
Not Applicable |
Aggregation
执行任何类型的所需聚合,并允许在 LINQ 中创建自定义聚合。
Performs any type of desired aggregation and allows creating custom aggregations in LINQ.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Aggregate |
Operates on the values of a collection to perform custom aggregation operation |
Not Applicable |
Not Applicable |
Average |
Average value of a collection of values is calculated |
Not Applicable |
Aggregate … In … Into Average() |
Count |
Counts the elements satisfying a predicate function within collection |
Not Applicable |
Aggregate … In … Into Count() |
LonCount |
Counts the elements satisfying a predicate function within a huge collection |
Not Applicable |
Aggregate … In … Into LongCount() |
Max |
Find out the maximum value within a collection |
Not Applicable |
Aggregate … In … Into Max() |
Min |
Find out the minimum value existing within a collection |
Not Applicable |
Aggregate … In … Into Min() |
Sum |
Find out the sum of a values within a collection |
Not Applicable |
Aggregate … In … Into Sum() |
Quantifier Operations
当序列中某些或所有元素满足特定条件时,这些运算符会返回布尔值,即 True 或 False。
These operators return a Boolean value i.e. True or False when some or all elements within a sequence satisfy a specific condition.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
All |
Returns a value ‘True’ if all elements of a sequence satisfy a predicate condition |
Not Applicable |
Aggregate … In … Into All(…) |
Any |
Determines by searching a sequence that whether any element of the same satisfy a specified condition |
Not Applicable |
Aggregate … In … Into Any() |
Contains |
Returns a ‘True’ value if finds that a specific element is there in a sequence if the sequence doe not contains that specific element , ‘false’ value is returned |
Not Applicable |
Not Applicable |
Partition Operators
将输入序列划分为不重新排列序列元素的两个独立部分,然后返回其中之一。
Divide an input sequence into two separate sections without rearranging the elements of the sequence and then returning one of them.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Skip |
Skips some specified number of elements within a sequence and returns the remaining ones |
Not Applicable |
Skip |
SkipWhile |
Same as that of Skip with the only exception that number of elements to skip are specified by a Boolean condition |
Not Applicable |
Skip While |
Take |
Take a specified number of elements from a sequence and skip the remaining ones |
Not Applicable |
Take |
TakeWhile |
Same as that of Take except the fact that number of elements to take are specified by a Boolean condition |
Not Applicable |
Take While |
Generation Operations
新值序列由生成运算符创建。
A new sequence of values is created by generational operators.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
DefaultIfEmpty |
When applied to an empty sequence, generate a default element within a sequence |
Not Applicable |
Not Applicable |
Empty |
Returns an empty sequence of values and is the most simplest generational operator |
Not Applicable |
Not Applicable |
Range |
Generates a collection having a sequence of integers or numbers |
Not Applicable |
Not Applicable |
Repeat |
Generates a sequence containing repeated values of a specific length |
Not Applicable |
Not Applicable |
Set Operations
集合运算有四个运算符,每个运算符根据不同的条件产生结果。
There are four operators for the set operations, each yielding a result based on different criteria.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
Distinct |
Results a list of unique values from a collection by filtering duplicate data if any |
Not Applicable |
Distinct |
Except |
Compares the values of two collections and return the ones from one collection who are not in the other collection |
Not Applicable |
Not Applicable |
Intersect |
Returns the set of values found t be identical in two separate collections |
Not Applicable |
Not Applicable |
Union |
Combines content of two different collections into a single list that too without any duplicate content |
Not Applicable |
Not Applicable |
Equality
比较两个句子(可枚举的),并确定它们是否完全匹配。
Compares two sentences (enumerable ) and determine are they an exact match or not.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
SequenceEqual |
Results a Boolean value if two sequences are found to be identical to each other |
Not Applicable |
Not Applicable |
Element Operators
除了 DefaultIfEmpty,所有其他八个标准查询元素运算符都会从一个集合返回一个单一元素。
Except the DefaultIfEmpty, all the rest eight standard query element operators return a single element from a collection.
Operator |
Description |
C# Query Expression Syntax |
VB Query Expression Syntax |
ElementAt |
Returns an element present within a specific index in a collection |
Not Applicable |
Not Applicable |
ElementAtOrDefault |
Same as ElementAt except of the fact that it also returns a default value in case the specific index is out of range |
Not Applicable |
Not Applicable |
First |
Retrieves the first element within a collection or the first element satisfying a specific condition |
Not Applicable |
Not Applicable |
FirstOrDefault |
Same as First except the fact that it also returns a default value in case there is no existence of such elements |
Not Applicable |
Not Applicable |
Last |
Retrieves the last element present in a collection or the last element satisfying a specific condition |
Not Applicable |
Not Applicable |
LastOrDefault |
Same as Last except the fact that it also returns a default value in case there is no existence of any such element |
Not Applicable |
Not Applicable |
Single |
Returns the lone element of a collection or the lone element that satisfy a certain condition |
Not Applicable |
Not Applicable |
SingleOrDefault |
Same as Single except that it also returns a default value if there is no existence of any such lone element |
Not Applicable |
Not Applicable |
DefaultIfEmpty |
Returns a default value if the collection or list is empty or null |
Not Applicable |
Not Applicable |
LINQ - SQL
LINQ to SQL 为管理对象关系数据提供一个基础结构(运行时)。它是 .NET Framework 3.5 版本的一个组件,能够将对象模型的语言集成查询翻译成 SQL。然后将这些查询发送到数据库以供执行。在从数据库获取结果后,LINQ to SQL 会再次将结果转换为对象。
LINQ to SQL offers an infrastructure (run-time) for the management of relational data as objects. It is a component of version 3.5 of the .NET Framework and ably does the translation of language-integrated queries of the object model into SQL. These queries are then sent to the database for the purpose of execution. After obtaining the results from the database, LINQ to SQL again translates them to objects.
Introduction of LINQ To SQL
对于大多数的 ASP.NET 开发人员而言,LINQ to SQL(也称为 DLINQ)是语言集成查询中令人振奋的部分,因为它可以通过使用通常的 LINQ 表达式来查询 SQL 服务器数据库。它还允许更新、删除和插入数据,但它所遭受的唯一缺点是它仅限于 SQL 服务器数据库。然而,LINQ to SQL 相较于 ADO.NET 具有许多优势,例如复杂度降低、编码行数减少等等。
For most ASP.NET developers, LINQ to SQL (also known as DLINQ) is an electrifying part of Language Integrated Query as this allows querying data in SQL server database by using usual LINQ expressions. It also allows to update, delete, and insert data, but the only drawback from which it suffers is its limitation to the SQL server database. However, there are many benefits of LINQ to SQL over ADO.NET like reduced complexity, few lines of coding and many more.
以下是显示 LINQ to SQL 执行架构的图表。
Below is a diagram showing the execution architecture of LINQ to SQL.
How to Use LINQ to SQL?
Step 1 - 与数据库服务器建立新的“数据连接”。查看 & Farrar; 服务器资源管理器 & Farrar; 数据连接 & Farrar; 添加连接
Step 1 − Make a new “Data Connection” with database server. View &arrar; Server Explorer &arrar; Data Connections &arrar; Add Connection
Step 2 - 添加 LINQ To SQL 类文件
Step 2 − Add LINQ To SQL class file
Step 3 - 从数据库中选择表并将其拖放到新的 LINQ to SQL 类文件中。
Step 3 − Select tables from database and drag and drop into the new LINQ to SQL class file.
Step 4 - 已将表添加到类文件中。
Step 4 − Added tables to class file.
Querying with LINQ to SQL
使用 LINQ to SQL 执行查询的规则类似于标准 LINQ 查询,即延迟或立即执行查询。有各种组件在使用 LINQ to SQL 执行查询中发挥作用,如下所示。
The rules for executing a query with LINQ to SQL is similar to that of a standard LINQ query i.e. query is executed either deferred or immediate. There are various components that play a role in execution of a query with LINQ to SQL and these are the following ones.
-
LINQ to SQL API − requests query execution on behalf of an application and sent it to LINQ to SQL Provider.
-
LINQ to SQL Provider − converts query to Transact SQL(T-SQL) and sends the new query to the ADO Provider for execution.
-
ADO Provider − After execution of the query, send the results in the form of a DataReader to LINQ to SQL Provider which in turn converts it into a form of user object.
需要注意的是,在执行 LINQ to SQL 查询之前,必须通过 DataContext 类连接到数据源。
It should be noted that before executing a LINQ to SQL query, it is vital to connect to the data source via DataContext class.
Insert, Update and Delete using LINQ To SQL
Add OR Insert
C#
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
//Create new Employee
Employee newEmployee = new Employee();
newEmployee.Name = "Michael";
newEmployee.Email = "yourname@companyname.com";
newEmployee.ContactNo = "343434343";
newEmployee.DepartmentId = 3;
newEmployee.Address = "Michael - USA";
//Add new Employee to database
db.Employees.InsertOnSubmit(newEmployee);
//Save changes to Database.
db.SubmitChanges();
//Get new Inserted Employee
Employee insertedEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("Michael"));
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}, Address = {4}",
insertedEmployee.EmployeeId, insertedEmployee.Name, insertedEmployee.Email,
insertedEmployee.ContactNo, insertedEmployee.Address);
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim newEmployee As New Employee()
newEmployee.Name = "Michael"
newEmployee.Email = "yourname@companyname.com"
newEmployee.ContactNo = "343434343"
newEmployee.DepartmentId = 3
newEmployee.Address = "Michael - USA"
db.Employees.InsertOnSubmit(newEmployee)
db.SubmitChanges()
Dim insertedEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("Michael"))
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3},
Address = {4}", insertedEmployee.EmployeeId, insertedEmployee.Name,
insertedEmployee.Email, insertedEmployee.ContactNo, insertedEmployee.Address)
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
编译并运行 C# 或 VB 的上述代码后,会产生以下结果 −
When the above code of C# or VB is compiled and run, it produces the following result −
Emplyee ID = 4, Name = Michael, Email = yourname@companyname.com, ContactNo =
343434343, Address = Michael - USA
Press any key to continue.
Update
C#
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
//Get Employee for update
Employee employee = db.Employees.FirstOrDefault(e =>e.Name.Equals("Michael"));
employee.Name = "George Michael";
employee.Email = "yourname@companyname.com";
employee.ContactNo = "99999999";
employee.DepartmentId = 2;
employee.Address = "Michael George - UK";
//Save changes to Database.
db.SubmitChanges();
//Get Updated Employee
Employee updatedEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("George Michael"));
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}, Address = {4}",
updatedEmployee.EmployeeId, updatedEmployee.Name, updatedEmployee.Email,
updatedEmployee.ContactNo, updatedEmployee.Address);
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim employee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("Michael"))
employee.Name = "George Michael"
employee.Email = "yourname@companyname.com"
employee.ContactNo = "99999999"
employee.DepartmentId = 2
employee.Address = "Michael George - UK"
db.SubmitChanges()
Dim updatedEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("George Michael"))
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3},
Address = {4}", updatedEmployee.EmployeeId, updatedEmployee.Name,
updatedEmployee.Email, updatedEmployee.ContactNo, updatedEmployee.Address)
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
编译并运行 C# 或 Vb 的上述代码后,会产生以下结果 −
When the above code of C# or Vb is compiled and run, it produces the following result −
Emplyee ID = 4, Name = George Michael, Email = yourname@companyname.com, ContactNo =
999999999, Address = Michael George - UK
Press any key to continue.
Delete
C#
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = newLinqToSQLDataContext(connectString);
//Get Employee to Delete
Employee deleteEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("George Michael"));
//Delete Employee
db.Employees.DeleteOnSubmit(deleteEmployee);
//Save changes to Database.
db.SubmitChanges();
//Get All Employee from Database
var employeeList = db.Employees;
foreach (Employee employee in employeeList) {
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}",
employee.EmployeeId, employee.Name, employee.Email, employee.ContactNo);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim deleteEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("George Michael"))
db.Employees.DeleteOnSubmit(deleteEmployee)
db.SubmitChanges()
Dim employeeList = db.Employees
For Each employee As Employee In employeeList
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}",
employee.EmployeeId, employee.Name, employee.Email, employee.ContactNo)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
编译并运行 C# 或 VB 的上述代码后,会产生以下结果 −
When the above code of C# or VB is compiled and run, it produces the following result −
Emplyee ID = 1, Name = William, Email = abc@gy.co, ContactNo = 999999999
Emplyee ID = 2, Name = Miley, Email = amp@esds.sds, ContactNo = 999999999
Emplyee ID = 3, Name = Benjamin, Email = asdsad@asdsa.dsd, ContactNo =
Press any key to continue.
LINQ - Objects
LINQ to Objects 提供对任何支持 IEnumerable<T> 的 LINQ 查询的使用,用于访问内存中数据集合,无需 LINQ 提供程序 (API),如 LINQ to SQL 或 LINQ to XML。
LINQ to Objects offers usage of any LINQ query supporting IEnumerable<T>for accessing in-memory data collections without any need of LINQ provider (API) as in case of LINQ to SQL or LINQ to XML.
Introduction of LINQ to Objects
LINQ to Objects 中的查询通常仅返回类型为 IEnumerable<T> 的变量。简而言之,LINQ to Objects 提供了一种新的集合方法,如前所述,以前必须编写长编码(非常复杂的 foreach 循环)才能从集合中检索数据,现在已替换为编写声明性代码,其中明确描述了需要检索的目标数据。
Queries in LINQ to Objects return variables of type usually IEnumerable<T> only. In short, LINQ to Objects offers a fresh approach to collections as earlier, it was vital to write long coding (foreach loops of much complexity) for retrieval of data from a collection which is now replaced by writing declarative code which clearly describes the desired data that is required to retrieve.
LINQ to Objects 还比传统的 foreach 循环具有更多的优势,例如,可读性更好,过滤功能更强大,分组功能更强大,增强排序功能,同时应用程序编码更少。此类 LINQ 查询本质上也更紧凑,并且可以移植到任何其他数据源,而无需进行任何修改或只需进行少量修改。
There are also many advantages of LINQ to Objects over traditional foreach loops like more readability, powerful filtering, capability of grouping, enhanced ordering with minimal application coding. Such LINQ queries are also more compact in nature and are portable to any other data sources without any modification or with just a little modification.
下面是一个简单的 LINQ to Objects 示例:
Below is a simple LINQ to Objects example −
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQtoObjects {
class Program {
static void Main(string[] args) {
string[] tools = { "Tablesaw", "Bandsaw", "Planer", "Jointer", "Drill", "Sander" };
var list = from t in tools select t;
StringBuilder sb = new StringBuilder();
foreach (string s in list) {
sb.Append(s + Environment.NewLine);
}
Console.WriteLine(sb.ToString(), "Tools");
Console.ReadLine();
}
}
}
在该示例中,字符串数组(工具)用作使用 LINQ to Objects 查询的对象集合。
In the example, an array of strings (tools) is used as the collection of objects to be queried using LINQ to Objects.
Objects query is:
var list = from t in tools select t;
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
Tablesaw
Bandsaw
Planer
Jointer
Drill
Sander
Querying in Memory Collections Using LINQ to Objects
C
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQtoObjects {
class Department {
public int DepartmentId { get; set; }
public string Name { get; set; }
}
class LinqToObjects {
static void Main(string[] args) {
List<Department> departments = new List<Department>();
departments.Add(new Department { DepartmentId = 1, Name = "Account" });
departments.Add(new Department { DepartmentId = 2, Name = "Sales" });
departments.Add(new Department { DepartmentId = 3, Name = "Marketing" });
var departmentList = from d in departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Module Module1
Sub Main(ByVal args As String())
Dim account As New Department With {.Name = "Account", .DepartmentId = 1}
Dim sales As New Department With {.Name = "Sales", .DepartmentId = 2}
Dim marketing As New Department With {.Name = "Marketing", .DepartmentId = 3}
Dim departments As New System.Collections.Generic.List(Of Department)(New Department() {account, sales, marketing})
Dim departmentList = From d In departments
For Each dept In departmentList
Console.WriteLine("Department Id = {0} , Department Name = {1}", dept.DepartmentId, dept.Name)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Class Department
Public Property Name As String
Public Property DepartmentId As Integer
End Class
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Department Id = 1, Department Name = Account
Department Id = 2, Department Name = Sales
Department Id = 3, Department Name = Marketing
Press any key to continue.
LINQ - Dataset
数据集在内存中提供了非常有用的数据表示形式,并且用于各种基于数据的应用程序。作为 LINQ to ADO.NET 技术之一的 LINQ to Dataset 促进了对数据集数据执行查询的便利,并且提高了工作效率。
A Dataset offers an extremely useful data representation in memory and is used for a diverse range of data based applications. LINQ to Dataset as one of the technology of LINQ to ADO.NET facilitates performing queries on the data of a Dataset in a hassle-free manner and enhance productivity.
Introduction of LINQ To Dataset
LINQ to Dataset 使查询任务对开发人员来说变得简单。他们不需要使用特定查询语言编写查询,而可以用编程语言编写相同的查询。LINQ to Dataset 也可用于从多个数据源合并数据时的查询。这也无需任何 LINQ 提供程序,比如 LINQ to SQL 和 LINQ to XML,就可以从内存集合中访问数据。
LINQ to Dataset has made the task of querying simple for the developers. They don’t need to write queries in a specific query language instead the same can be written in programming language. LINQ to Dataset is also usable for querying where data is consolidated from multiple data sources. This also does not need any LINQ provider just like LINQ to SQL and LINQ to XML for accessing data from in memory collections.
以下是 LINQ to Dataset 查询的简单示例,其中首先获取数据源,然后使用两个数据表填充数据集。在两个表之间建立关系,然后通过联接子句对两个表创建 LINQ 查询。最后,使用 foreach 循环显示所需结果。
Below is a simple example of a LINQ to Dataset query in which a data source is first obtained and then the dataset is filled with two data tables. A relationship is established between both the tables and a LINQ query is created against both tables by the means of join clause. Finally, foreach loop is used to display the desired results.
C
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LINQtoDataset {
class Program {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
string sqlSelect = "SELECT * FROM Department;" + "SELECT * FROM Employee;";
// Create the data adapter to retrieve data from the database
SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connectString);
// Create table mappings
da.TableMappings.Add("Table", "Department");
da.TableMappings.Add("Table1", "Employee");
// Create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);
DataRelation dr = ds.Relations.Add("FK_Employee_Department",
ds.Tables["Department"].Columns["DepartmentId"],
ds.Tables["Employee"].Columns["DepartmentId"]);
DataTable department = ds.Tables["Department"];
DataTable employee = ds.Tables["Employee"];
var query = from d in department.AsEnumerable()
join e in employee.AsEnumerable()
on d.Field<int>("DepartmentId") equals
e.Field<int>("DepartmentId")
select new {
EmployeeId = e.Field<int>("EmployeeId"),
Name = e.Field<string>("Name"),
DepartmentId = d.Field<int>("DepartmentId"),
DepartmentName = d.Field<string>("Name")
};
foreach (var q in query) {
Console.WriteLine("Employee Id = {0} , Name = {1} , Department Name = {2}",
q.EmployeeId, q.Name, q.DepartmentName);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Data.SqlClient
Imports System.Linq
Module LinqToDataSet
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim sqlSelect As String = "SELECT * FROM Department;" + "SELECT * FROM Employee;"
Dim sqlCnn As SqlConnection = New SqlConnection(connectString)
sqlCnn.Open()
Dim da As New SqlDataAdapter
da.SelectCommand = New SqlCommand(sqlSelect, sqlCnn)
da.TableMappings.Add("Table", "Department")
da.TableMappings.Add("Table1", "Employee")
Dim ds As New DataSet()
da.Fill(ds)
Dim dr As DataRelation = ds.Relations.Add("FK_Employee_Department", ds.Tables("Department").Columns("DepartmentId"), ds.Tables("Employee").Columns("DepartmentId"))
Dim department As DataTable = ds.Tables("Department")
Dim employee As DataTable = ds.Tables("Employee")
Dim query = From d In department.AsEnumerable()
Join e In employee.AsEnumerable() On d.Field(Of Integer)("DepartmentId") Equals
e.Field(Of Integer)("DepartmentId")
Select New Person With { _
.EmployeeId = e.Field(Of Integer)("EmployeeId"),
.EmployeeName = e.Field(Of String)("Name"),
.DepartmentId = d.Field(Of Integer)("DepartmentId"),
.DepartmentName = d.Field(Of String)("Name")
}
For Each e In query
Console.WriteLine("Employee Id = {0} , Name = {1} , Department Name = {2}", e.EmployeeId, e.EmployeeName, e.DepartmentName)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Class Person
Public Property EmployeeId As Integer
Public Property EmployeeName As String
Public Property DepartmentId As Integer
Public Property DepartmentName As String
End Class
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Employee Id = 1, Name = William, Department Name = Account
Employee Id = 2, Name = Benjamin, Department Name = Account
Employee Id = 3, Name = Miley, Department Name = Sales
Press any key to continue.
Querying Dataset using LinQ to Dataset
在使用 LINQ to Dataset 查询数据集之前,至关重要的是将数据加载到数据集,这是通过使用 DataAdapter 类或通过 LINQ to SQL 来完成的。使用 LINQ to Dataset 制定的查询与使用 LINQ 以及其他启用了 LINQ 的数据源来制定查询非常相似。
Before beginning querying a Dataset using LINQ to Dataset, it is vital to load data to a Dataset and this is done by either using DataAdapter class or by LINQ to SQL. Formulation of queries using LINQ to Dataset is quite similar to formulating queries by using LINQ alongside other LINQ enabled data sources.
Single-Table Query
在以下单表查询中,从 SalesOrderHeaderTtable 收集所有在线订单,然后显示订单 ID、订单日期以及订单编号作为输出。
In the following single-table query, all online orders are collected from the SalesOrderHeaderTtable and then order ID, Order date as well as order number are displayed as output.
C#
C#
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinqToDataset {
class SingleTable {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
string sqlSelect = "SELECT * FROM Department;";
// Create the data adapter to retrieve data from the database
SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connectString);
// Create table mappings
da.TableMappings.Add("Table", "Department");
// Create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);
DataTable department = ds.Tables["Department"];
var query = from d in department.AsEnumerable()
select new {
DepartmentId = d.Field<int>("DepartmentId"),
DepartmentName = d.Field<string>("Name")
};
foreach (var q in query) {
Console.WriteLine("Department Id = {0} , Name = {1}",
q.DepartmentId, q.DepartmentName);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
VB
Imports System.Data.SqlClient
Imports System.Linq
Module LinqToDataSet
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim sqlSelect As String = "SELECT * FROM Department;"
Dim sqlCnn As SqlConnection = New SqlConnection(connectString)
sqlCnn.Open()
Dim da As New SqlDataAdapter
da.SelectCommand = New SqlCommand(sqlSelect, sqlCnn)
da.TableMappings.Add("Table", "Department")
Dim ds As New DataSet()
da.Fill(ds)
Dim department As DataTable = ds.Tables("Department")
Dim query = From d In department.AsEnumerable()
Select New DepartmentDetail With {
.DepartmentId = d.Field(Of Integer)("DepartmentId"),
.DepartmentName = d.Field(Of String)("Name")
}
For Each e In query
Console.WriteLine("Department Id = {0} , Name = {1}", e.DepartmentId, e.DepartmentName)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Public Class DepartmentDetail
Public Property DepartmentId As Integer
Public Property DepartmentName As String
End Class
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Department Id = 1, Name = Account
Department Id = 2, Name = Sales
Department Id = 3, Name = Pre-Sales
Department Id = 4, Name = Marketing
Press any key to continue.
LINQ - XML
LINQ to XML 提供了对所有 LINQ 功能的轻松访问,例如标准查询运算符、编程接口等。LINQ to XML 集成了 .NET 框架中,还可以充分利用 .NET 框架功能,如调试、编译时检查、强类型等等。
LINQ to XML offers easy accessibility to all LINQ functionalities like standard query operators, programming interface, etc. Integrated in the .NET framework, LINQ to XML also makes the best use of .NET framework functionalities like debugging, compile-time checking, strong typing and many more to say.
Introduction of LINQ to XML
在使用 LINQ to XML 时,可以轻松地将 XML 文档加载到内存中,并且更容易查询和修改文档。还可以将内存中现有的 XML 文档保存到磁盘并对其进行序列化。它消除了开发人员学习有些复杂的 XML 查询语言的需要。
While using LINQ to XML, loading XML documents into memory is easy and more easier is querying and document modification. It is also possible to save XML documents existing in memory to disk and to serialize them. It eliminates the need for a developer to learn the XML query language which is somewhat complex.
LINQ to XML 的功能在 System.Xml.Linq 命名空间中。这拥有 19 个与 XML 配合使用必不可少的类。这些类如下。
LINQ to XML has its power in the System.Xml.Linq namespace. This has all the 19 necessary classes to work with XML. These classes are the following ones.
-
XAttribute
-
XCData
-
XComment
-
XContainer
-
XDeclaration
-
XDocument
-
XDocumentType
-
XElement
-
XName
-
XNamespace
-
XNode
-
XNodeDocumentOrderComparer
-
XNodeEqualityComparer
-
XObject
-
XObjectChange
-
XObjectChangeEventArgs
-
XObjectEventHandler
-
XProcessingInstruction
-
XText
Read an XML File using LINQ
C
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(ByVal args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Department Name - Account
Department Name - Sales
Department Name - Pre-Sales
Department Name - Marketing
Press any key to continue.
Add New Node
C
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
//Add new Element
xdoc.Element("Departments").Add(new XElement("Department", "Finance"));
//Add new Element at First
xdoc.Element("Departments").AddFirst(new XElement("Department", "Support"));
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(ByVal args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
xdoc.Element("Departments").Add(New XElement("Department", "Finance"))
xdoc.Element("Departments").AddFirst(New XElement("Department", "Support"))
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Department Name - Support
Department Name - Account
Department Name - Sales
Department Name - Pre-Sales
Department Name - Marketing
Department Name - Finance
Press any key to continue.
Deleting Particular Node
C
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Support</Department>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
<Department>Finance</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
//Remove Sales Department
xdoc.Descendants().Where(s =>s.Value == "Sales").Remove();
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Support</Department>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"<Department>Finance</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
xdoc.Descendants().Where(Function(s) s.Value = "Sales").Remove()
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
Department Name - Support
Department Name - Account
Department Name - Pre-Sales
Department Name - Marketing
Department Name - Finance
Press any key to continue.
LINQ - Entities
作为 ADO.NET 实体框架的一部分,LINQ to Entities 比 LINQ to SQL 更灵活,但由于其复杂性和缺乏关键特性而不太流行。但是,它没有 LINQ to SQL 的限制,后者仅允许在 SQL Server 数据库中进行数据查询,因为 LINQ to Entities 可以在大量数据提供程序(如 Oracle、MySQL 等)中促进数据查询。
A part of the ADO.NET Entity Framework, LINQ to Entities is more flexible than LINQ to SQL, but is not much popular because of its complexity and lack of key features. However, it does not have the limitations of LINQ to SQL that allows data query only in SQL server database as LINQ to Entities facilitates data query in a large number of data providers like Oracle, MySQL, etc.
此外,它得到了 ASP.Net 的大力支持,这意味着用户可以利用数据源控件通过 LINQ to Entities 执行查询,并促进结果的绑定,而无需任何额外的编码。
Moreover, it has got a major support from ASP.Net in the sense that users can make use of a data source control for executing a query via LINQ to Entities and facilitates binding of the results without any need of extra coding.
LINQ to Entities 凭借这些优势已成为目前面向数据库使用 LINQ 的标准机制。使用 LINQ to Entities 还可以更改查询的数据详细信息,并轻松地提交批处理更新。最吸引人的是,LINQ to Entities 具有与 SQL 相同的语法,甚至拥有相同的标准查询操作符组,如“联接”、“选择”、“按顺序排列”等。
LINQ to Entities has for these advantages become the standard mechanism for the usage of LINQ on databases nowadays. It is also possible with LINQ to Entities to change queried data details and committing a batch update easily. What is the most intriguing fact about LINQ to Entities is that it has same syntax like that of SQL and even has the same group of standard query operators like Join, Select, OrderBy, etc.
LINQ to Entities Query Creation and Execution Process
-
Construction of an ObjectQuery instance out of an ObjectContext (Entity Connection)
-
Composing a query either in C# or Visual Basic (VB) by using the newly constructed instance
-
Conversion of standard query operators of LINQ as well as LINQ expressions into command trees
-
Executing the query passing any exceptions encountered to the client directly
-
Returning to the client all the query results
ObjectContext 这里的主要类,可与 Entity Data Model 交互;换句话说,它起到了 LINQ 与数据库之间的桥梁作用。命令树这里是为了与 Entity 框架兼容的查询表示形式。
ObjectContext is here the primary class that enables interaction with Entity Data Model or in other words acts as a bridge that connects LINQ to the database. Command trees are here query representation with compatibility with the Entity framework.
另一方面,Entity Framework 实际上是 Object Relational Mapper ,开发人员通常将其缩写为 ORM,它可以根据数据库表生成业务对象以及实体,并支持各种基本操作,如创建、更新、删除和读取。下图显示了 Entity 框架及其组件。
The Entity Framework, on the other hand, is actually Object Relational Mapper abbreviated generally as ORM by the developers that does the generation of business objects as well as entities as per the database tables and facilitates various basic operations like create, update, delete and read. The following illustration shows the entity framework and its components.
Example of ADD, UPDATE, and DELETE using LINQ with Entity Model
首先按照以下步骤添加 Entity 模型。
First add Entity Model by following below steps.
Step 1 − 右键单击项目,然后单击添加新项目,将打开如下图所示的窗口。选择 ADO.NET Entity Data Model,指定名称,然后单击添加。
Step 1 − Right click on project and click add new item will open window as per below. Select ADO.NET Entity Data Model and specify name and click on Add.
Step 2 − 选择 Generate from database.
Step 2 − Select Generate from database.
Step 3 − 从下拉菜单中选择数据库连接。
Step 3 − Choose Database Connection from the drop-down menu.
Step 4 − 选择所有表。
Step 4 − Select all the tables.
现在编写以下代码。
Now write the following code.
using DataAccess;
using System;
using System.Linq;
namespace LINQTOSQLConsoleApp {
public class LinqToEntityModel {
static void Main(string[] args) {
using (LinqToSQLDBEntities context = new LinqToSQLDBEntities()) {
//Get the List of Departments from Database
var departmentList = from d in context.Departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
//Add new Department
DataAccess.Department department = new DataAccess.Department();
department.Name = "Support";
context.Departments.Add(department);
context.SaveChanges();
Console.WriteLine("Department Name = Support is inserted in Database");
//Update existing Department
DataAccess.Department updateDepartment = context.Departments.FirstOrDefault(d ⇒d.DepartmentId == 1);
updateDepartment.Name = "Account updated";
context.SaveChanges();
Console.WriteLine("Department Name = Account is updated in Database");
//Delete existing Department
DataAccess.Department deleteDepartment = context.Departments.FirstOrDefault(d ⇒d.DepartmentId == 3);
context.Departments.Remove(deleteDepartment);
context.SaveChanges();
Console.WriteLine("Department Name = Pre-Sales is deleted in Database");
//Get the Updated List of Departments from Database
departmentList = from d in context.Departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
LINQ - Lambda Expressions
术语“Lambda 表达式”是从“lambda”演算派生而来的,而“lambda”演算本身是一种用于定义函数的数学表示法。作为 LINQ 等式的可执行部分的 lambda 表达式以一种方式转换逻辑,以便在运行时可以方便地传递给数据源。但是,lambda 表达式不仅限于在 LINQ 中寻找应用程序。
The term ‘Lambda expression’ has derived its name from ‘lambda’ calculus which in turn is a mathematical notation applied for defining functions. Lambda expressions as a LINQ equation’s executable part translate logic in a way at run time so it can pass on to the data source conveniently. However, lambda expressions are not just limited to find application in LINQ only.
这些表达式用以下语法表示 -
These expressions are expressed by the following syntax −
(Input parameters) ⇒ Expression or statement block
以下是 lambda 表达式的示例 -
Here is an example of a lambda expression −
y ⇒ y * y
上述表达式指定了一个名为 y 的参数,并且 y 的值为平方。但是,无法以这种形式执行 lambda 表达式。下面展示了 C# 中 lambda 表达式的示例。
The above expression specifies a parameter named y and that value of y is squared. However, it is not possible to execute a lambda expression in this form. Example of a lambda expression in C# is shown below.
C
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
delegate int del(int i);
static void Main(string[] args) {
del myDelegate = y ⇒ y * y;
int j = myDelegate(5);
Console.WriteLine(j);
Console.ReadLine();
}
}
}
VB
Module Module1
Private Delegate Function del(ByVal i As Integer) As Integer
Sub Main(ByVal args As String())
Dim myDelegate As del = Function(y) y * y
Dim j As Integer = myDelegate(5)
Console.WriteLine(j)
Console.ReadLine()
End Sub
End Module
当以上 C# 或 VB 代码被编译并执行时,它会生成以下结果 -
When the above code of C# or VB is compiled and executed, it produces the following result −
25
Expression Lambda
由于 lambda 表达式语法中的表达式位于右侧,因此它们也被称为表达式 lambda。
As the expression in the syntax of lambda expression shown above is on the right hand side, these are also known as expression lambda.
Async Lambdas
通过使用 async 关键字结合异步处理创建的 lambda 表达式称为异步 lambda。以下是一个异步 lambda 示例。
The lambda expression created by incorporating asynchronous processing by the use of async keyword is known as async lambdas. Below is an example of async lambda.
Func<Task<string>> getWordAsync = async()⇒ “hello”;
Lambda in Standard Query Operators
查询运算符中的 lambda 表达式由同个运算符根据需要进行求值,并持续处理输入序列中的每个元素,而不是整个序列。Lambda 表达式允许开发人员将自己的逻辑提供给标准查询运算符。在以下示例中,开发人员使用“Where”运算符通过使用 lambda 表达式从给定列表中回收奇数。
A lambda expression within a query operator is evaluated by the same upon demand and continually works on each of the elements in the input sequence and not the whole sequence. Developers are allowed by Lambda expression to feed their own logic into the standard query operators. In the below example, the developer has used the ‘Where’ operator to reclaim the odd values from given list by making use of a lambda expression.
C
//Get the average of the odd Fibonacci numbers in the series...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
static void Main(string[] args) {
int[] fibNum = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
double averageValue = fibNum.Where(num ⇒ num % 2 == 1).Average();
Console.WriteLine(averageValue);
Console.ReadLine();
}
}
}
VB
Module Module1
Sub Main()
Dim fibNum As Integer() = {1, 1, 2, 3, 5, 8, 13, 21, 34}
Dim averageValue As Double = fibNum.Where(Function(num) num Mod 2 = 1).Average()
Console.WriteLine(averageValue)
Console.ReadLine()
End Sub
End Module
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
7.33333333333333
Type Inference in Lambda
在 C# 中,类型推断在各种情况下得到了方便的使用,甚至无需显式指定类型。然而,在 lambda 表达式的情况下,类型推断仅在编译器必须满足时才起作用,前提是每个类型都已指定。我们来看一下下面的示例。
In C#, type inference is used conveniently in a variety of situations and that too without specifying the types explicitly. However in case of a lambda expression, type inference will work only when each type has been specified as the compiler must be satisfied. Let’s consider the following example.
delegate int Transformer (int i);
这里,编译器利用类型推断根据 Transformer 的参数类型来利用 x 是一个整数这一事实。
Here the compiler employ the type inference to draw upon the fact that x is an integer and this is done by examining the parameter type of the Transformer.
Variable Scope in Lambda Expression
在 lambda 表达式中使用变量范围时有一些规则,例如在 lambda 表达式中启动的变量不得在外部方法中可见。还有一条规则,即捕获变量不得被垃圾回收,除非引用它的委托符合垃圾回收行为。此外,还有一条规则禁止 lambda 表达式中的 return 语句导致包围方法返回。
There are some rules while using variable scope in a lambda expression like variables that are initiated within a lambda expression are not meant to be visible in an outer method. There is also a rule that a captured variable is not to be garbage collected unless the delegate referencing the same becomes eligible for the act of garbage collection. Moreover, there is a rule that prohibits a return statement within a lambda expression to cause return of an enclosing method.
这里有一个示例来说明 lambda 表达式中的变量范围。
Here is an example to demonstrate variable scope in lambda expression.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
delegate bool D();
delegate bool D2(int i);
class Test {
D del;
D2 del2;
public void TestMethod(int input) {
int j = 0;
// Initialize the delegates with lambda expressions.
// Note access to 2 outer variables.
// del will be invoked within this method.
del = () ⇒ { j = 10; return j > input; };
// del2 will be invoked after TestMethod goes out of scope.
del2 = (x) ⇒ { return x == j; };
// Demonstrate value of j:
// The delegate has not been invoked yet.
Console.WriteLine("j = {0}", j); // Invoke the delegate.
bool boolResult = del();
Console.WriteLine("j = {0}. b = {1}", j, boolResult);
}
static void Main() {
Test test = new Test();
test.TestMethod(5);
// Prove that del2 still has a copy of
// local variable j from TestMethod.
bool result = test.del2(10);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
}
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
j = 0
j = 10. b = True
True
Expression Tree
Lambda 表达式广泛用于 Expression Tree 构造。表达式树将代码赠送给类似树的数据结构,其中每个节点本身就是表达式,比如方法调用或二进制运算,比如 x<y。以下是一个用于构造表达式树的 lambda 表达式使用示例。
Lambda expressions are used in Expression Tree construction extensively. An expression tree give away code in a data structure resembling a tree in which every node is itself an expression like a method call or can be a binary operation like x<y. Below is an example of usage of lambda expression for constructing an expression tree.
Statement Lambda
还有包含两个或三个语句的 statement lambdas ,但未用于构造表达式树。必须在语句 lambda 中编写 return 语句。
There is also statement lambdas consisting of two or three statements, but are not used in construction of expression trees. A return statement must be written in a statement lambda.
语句 lambda 的语法
Syntax of statement lambda
(params)⇒ {statements}
Example of a statement lambda
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace lambdaexample {
class Program {
static void Main(string[] args) {
int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };
foreach (int i in source.Where(x ⇒
{
if (x <= 3)
return true;
else if (x >= 7)
return true;
return false;
}
))
Console.WriteLine(i);
Console.ReadLine();
}
}
}
编译并执行上述代码后,将产生以下结果 −
When the above code is compiled and executed, it produces the following result −
3
8
1
7
9
2
8
Lambda 作为基于方法的 LINQ 查询中的参数,永远不允许像 is 或 as 一样放在运算符的左侧,就像匿名方法一样。虽然 Lambda 表达式很像匿名方法,但它们完全不受限于仅用作委托。
Lambdas are employed as arguments in LINQ queries based on methods and never allowed to have a place on the left side of operators like is or as just like anonymous methods. Although, Lambda expressions are much alike anonymous methods, these are not at all restricted to be used as delegates only.
Points to remember while using lambda expressions
-
A lambda expression can return a value and may have parameters.
-
Parameters can be defined in a myriad of ways with a lambda expression.
-
If there is single statement in a lambda expression, there is no need of curly brackets whereas if there are multiple statements, curly brackets as well as return value are essential to write.
-
With lambda expressions, it is possible to access variables present outside of the lambda expression block by a feature known as closure. Use of closure should be done cautiously to avoid any problem.
-
It is impossible to execute any unsafe code inside any lambda expression.
-
Lambda expressions are not meant to be used on the operator’s left side.
LINQ - ASP.Net
作为一组 .NET 框架扩展,LINQ 是 ASP.NET 开发人员用于数据访问的首选机制。ASP.NET 3.5 有一个内置的工具 LINQDataSource 控件,可轻松在 ASP.NET 中使用 LINQ。ASP.NET 使用上述控件作为数据源。现实生活中的项目大多包含网站或 Windows 应用程序,因此为了更好地理解 LINQ 和 ASP.NET 的概念,让我们从创建利用 LINQ 特性的 ASP.NET 网站开始。
As a set of .NET framework extensions, LINQ is the preferred mechanism for data access by ASP.NET developers. ASP.NET 3.5 has a built-in tool LINQDataSource control that enables usage of LINQ easily in ASP.NET. ASP.NET uses the above-mentioned control as a data source. Real life projects mostly encompass websites or windows applications and so to understand better the concept of LINQ with ASP.NET, let’s start with creating a ASP.NET website that make use of the LINQ features.
为此,必须在您的系统上安装 Visual Studio 和 .NET 框架。在您打开 Visual Studio 后,转到“文件”→“新建”→“网站”。将打开一个弹出窗口,如下图中所示。
For this, it is essential to get installed Visual Studio and .NET framework on your system. Once you have opened Visual Studio, go to File → New → Website. A pop up window will open as shown in below figure.
现在,在左侧的模板下,将有两个用于创建网站的语言选项。选择 Visual C# 并选择 ASP.NET Empty Web Site 。
Now, under the templates in the left hand side, there will be two language options to create the website. Choose Visual C# and select ASP.NET Empty Web Site.
选择您想要将新网站保存在系统中的文件夹。然后按 OK 和 Solution Explorer ,出现包含所有 Web 文件的屏幕。在项目资源管理器中右键单击 Default.aspx,然后选择“在浏览器中查看”在浏览器中查看默认的 ASP.NET 网站。不久后,您的新 ASP.NET 网站将在网络浏览器中打开,如下面的屏幕截图所示。
Select the folder where you want to save new website on your system. Then press OK and soon Solution Explorer appears on your screen containing all the web files. Right click on Default.aspx in the Solution Explorer and choose View in Browser to view the default ASP.NET website in the browser. Soon your new ASP.NET website will open in the web browser, as shown in the following screenshot.
LINQDataSource Control
可以通过 LINQDataSource 控件,以 UPDATE, INSERT 和 DELETE 的方式在 ASP.NET 网站的页面中添加数据。绝对不需要指定 SQL 命令,因为 LINQDataSource 控件使用动态创建的命令执行此类操作。
It is possible to UPDATE, INSERT and DELETE data in the pages of ASP.NET website with the help of LINQDataSource control. There is absolutely no need for specification of SQL commands as LINQDataSource control employs dynamically created commands for such operations.
控件允许用户通过标记文本中的属性设置方便地在 ASP.NET 网页中使用 LINQ。LINQDataSource 与 SqlDataSource 以及 ObjectDataSource 等控件非常相似,因为它可以用来将页面上其他 ASP.NET 控件绑定到数据源。因此,我们必须有一个 database 来解释 LINQDataSource 控件调用的各种函数。
The control enables a user to make use of LINQ in an ASP.NET web page conveniently by property setting in the markup text. LINQDataSource is very similar to that of controls like SqlDataSource as well as ObjectDataSource as it can be used in binding other ASP.NET controls present on a page to a data source. So, we must have a database to explain the various functions invoked by the LINQDataSource Control.
在开始解释在 ASP.NET 网页表单中使用控件之前,必须打开 Microsoft Visual Studio 工具箱并将 LINQDataSource 控件拖放到 ASP.NET 网站的 .aspx 页面中(如下图所示)。
Before going to start explanation of the control usage in ASP.NET web page form, it is essential to open the Microsoft Visual Studio Toolbox and drag and drop LINQDataSource control to .aspx page of ASP.NET website like below figure.
下一步是通过选择员工记录的所有列来配置 LINQDataSource。
The next step is to configure LINQDataSource by selecting all the columns for the employee record.
现在将 GridView 控件添加到 .aspx 页面并像下图中所示一样对其进行配置。GridView 控件功能强大且具有灵活的数据处理能力。在配置控件后,它将出现在浏览器中。
Now add a GridView Control to the .aspx page and configure it like shown in below figure. The GridView control is powerful and offers flexibility to work with the data. Soon after configuring the control, it will appear in the browser.
现在可以在您的屏幕上看到 .aspx 页面的编码,如下所示:
The coding that can be viewed now on your screen for the .aspx page will be −
<!DOCTYPE html>
<html>
<head runat = "server">
<title></title>
</head>
<body>
<form id = "form1" runat = "server">
<div>
<asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
DataKeyNames = "ContactID" DataSourceID = "LINQDataSource1">
<Columns>
<asp:BoundField DataField = "ContactID" HeaderText = "ContactID"
InsertVisible = "False" ReadOnly="True" SortExpression = "ContactID" />
<asp:CheckBoxField DataField = "NameStyle" HeaderText = "NameStyle"
SortExpression = "NameStyle" />
<asp:BoundField DataField = "Title" HeaderText = "Title" SortExpression = "Title" />
<asp:BoundField DataField = "FirstName" HeaderText = "FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField = "MiddleName" HeaderText = "MiddleName"
SortExpression = "MiddleName" />
<asp:BoundField DataField = "LastName" HeaderText = "LastName"
SortExpression = "LastName" />
<asp:BoundField DataField = "Suffix" HeaderText = "Suffix"
SortExpression = "Suffix" />
<asp:BoundField DataField = "EmailAddress" HeaderText = "EmailAddress"
SortExpression = "EmailAddress" />
</Columns>
</asp:GridView>
<br />
</div>
<asp:LINQDataSource ID = "LINQDataSource1" runat = "server"
ContextTypeName = "LINQWebApp1.AdventureWorksDataContext" EntityTypeName = ""
TableName = "Contacts">
</asp:LINQDataSource>
</form>
</body>
</html>
这里应注意,将 ContextTypeName 属性设置为表示数据库的类的属性至关重要。例如,这里给出的 LINQWebApp1.AdventureWorksDataContext 将使 LINQDataSource 和数据库之间建立所需的连接。
Here it should be noted that it is vital to set the property ContextTypeName to that of the class representing the database. For example, here it is given as LINQWebApp1.AdventureWorksDataContext as this action will make the needed connection between LINQDataSource and the database.
INSERT, UPDATE, and DELETE data in ASP.NET Page using LINQ
在严格执行所有上述步骤后,从 LINQDataSource Control 中选择 LINQDataSource Tasks 选择 all three boxes用于启用插入、更新和删除,如下图所示。
After completing all the above steps rigorously, choose the LINQDataSource Tasks from the LINQDataSource Control and choose all the three boxes for enable insert, enable update and enable delete from the same, as shown in the following screenshot.
很快,声明性标记将以以下方式显示在您的屏幕上。
Soon the declarative markup will get displayed on your screen as the following one.
<asp:LINQDataSource
ContextTypeName = "LINQWebApp1.AdventureWorksDataContext"
TableName = "Contacts"
EnableUpdate = "true"
EnableInsert = "true"
EnableDelete = "true"
ID = "LINQDataSource1"
runat = "server">
</asp:LINQDataSource>
由于有多行和多列,因此最好在 .aspx 表单上添加另一个控件,将其命名为“详细信息”或“主控件”(位于网格视图控件下方),以仅显示网格中所选行的详细信息。从详细信息控件中选择详细信息任务,并选择复选框,如下所示。
Now since there are multiple rows and columns, it is better to add another control on your .aspx form named as Detail View or Master control below the Grid View control to display only the details of a selected row of the grid. Choose the Detail View Tasks from the Detail View control and select the check boxes as shown below.
现在,只需保存更改并按 Ctrl+F5 即可在浏览器中查看页面,现在可以在详细信息控件上删除、更新和插入任何记录。
Now, just save the changes and press Ctrl + F5 to view the page in your browser where it is now possible to delete, update, insert any record on the detail view control.