LINQ数据库访问技术
1 LINQ基础
LINQ(Language-Integrated Query,语言集成查询)是微软公司提供的一项新技术,它能够将查询功能直接引入到.NET Framework所支持的编程语言中。查询操作可以通过编程语言自身来传达,而不是以字符串形式嵌入到应用程序代码中。LINQ主要包括LINQ to SQL、LINK to DataSet、LINQ to Object和LINQ to XML四中关键技术。
1.1 LINQ概述
语言集成查询(LINQ)可以为C#和Visual Basic提供强大的查询功能。LINQ引入了标准的、易学习的查询和更新数据模式,可以对其技术进行扩展以支持几乎任何类型的数据存储。
LINK主要由三部分组成
①LINQ to ADO.NET(又分为LINQ to SQL和LINQ to DataSet)
②LINQ to Object
③LINQ to XML
LINQ可以查询或操作任何存储形式的数据。
组件 | 说明 |
---|---|
LINQ to SQL | 查询基于关系数据库的数据,并对这些数据进行检索、修改、删除、排序、集合、分区等操作 |
LINQ to DataSet | 可以查询DateSet对相关中的数据,并对这些数据进行检索、过滤、排序等操作 |
LINQ to Object | 可以查询lenumerable或lenumerable集合,也就是可以查询任何可枚举的集合,如数据(Array和ArrayList)、泛型列表List、泛型字典Dictionary等,以及用户自定义的集合,而不需要使用LINK提供程序或API |
LINQ to XML | 可以查询或操作XML结构的数据(如XML文档、XML片段、XML格式的字符串等),并提供了修改文档对象模型的内存文档和支持LINK查询表达式等功能,一级处理XML文档的全新的编程接口。 |
LINQ可以查询或操作任何存储形式的数,如对象(集合、数组。字符串等)、关系(关系数据库、ADO.NET数据集等)以及XML。
LINQ架构如图:
1.2 使用var创建隐型局部变量
C#1.0、1.1及2.0版本中,如果要声明一个变量,必须指定变量的类型,但在C#后期版本中声明变量时,可以不明确指定其数据类型,而使用关键字var来声明。var关键字用来创建隐型局部变量,它指示编译器根据初始化语句右侧的表达式推断变量的类型。推断类型可以使内置类型、匿名类型、用户定义类型、.NET Framework类库中定义的类型或任何表达式
例如使用var关键字声明一个隐型局部变量,并赋值2021,代码如下:
var number = 2014;
在很多情况下,var是可选的,它只是提供了语法上的遍历。但在使用匿名类型初始化变量时,需要使用它,这在LINQ查询表达式中很常见。由于只有编译器知道匿名类型的名称,因此必须在源代码中使用var。如果已经使用var初始化了查询变量,则还必须使用var作为查询变量进行循环访问的foreach语句中迭代变量的类型。
实例:
class Program
{
static void Main(string[] args)
{
string[] strwords = {
"ZhangSan", "LiSi", "WangWu" };
var ChangeWord = from word in strwords
select new {
Upper = word.ToUpper(), Lower = word.ToLower() };
foreach (var item in ChangeWord)
{
Console.WriteLine("大写:{0}--小写:{1}", item.Upper, item.Lower);
}
Console.ReadLine();
}
}
效果:
使用隐式类型的变量时,需要遵循一下规则:
①只有在同一语句中说明和初始化局部变量时,才能使用var;不能将该变量初始化为null;
②不能将var用于类范围的域
③有var声明的变量不能用在初始化表达式中,例如"var v = v ++",这样会产生编译时错误
④不能在同一语句中初始化多个隐式类型的变量
⑤如果一个名为var的类型位于范围中,则当尝试用var关键字初始化局部变量时,将产生编译错误。
1.3 Lambda表达式的使用
Lambda表达式是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。所有Lambda表达式都使用Lambda运算符"=>",(读为goes to)。Lambda运算符的左边是输入参数(如果有),右边包含表达式或语句块。列入Lambda表达式x=>x*x,读作x gose to times x。
Lambda表达式的基本形式如下:
(input parameters) => expression
//parameters表示输入参数、expression表示表达式
说明:
①Lambda表达式用在基于方法的LINQ查询中,作为诸如Where和Where(IQueryable、String、Object[])等标准查询运算符方法的参数
②使用基于方法的语法在Enumberable类中调用Where方法时(像在LINQ to Object和LINQ to XML中那样),参数是委托类型Func<T,TResult>,使用Lambda表达式创建委托最为方便。
注意:在is或as运算符的左侧不允许使用Lambda表达式
实例:
class Program
{
static void Main(string[] args)
{
string[] strLists = {
"编程词典", "C#编程词典", "C#程词典典藏版" };
string[] strList = Array.FindAll(strLists, s => (s.IndexOf("C#") >= 0));
foreach (string str in strList)
{
Console.WriteLine(str);
}
Console.ReadLine();
}
}
效果:
下列规则适用于Lambda表达式中的变量范围:
①捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止
②在外部方法中看不到Lambda表达式内引入的变量
③Lambda表达式无法从封闭方法中直接捕获ref或out参数
④Lambda表达式中的返回语句不会导致封闭方法返回
⑤Lambda表达式不能包含其目标位于所包含匿名函数主体外部或内部的goto语句、break语句或continue语句。
1.4 LINQ查询表达式
语言集成查询(LINQ)是一组技术的名称,这些技术建立在将查询功能直接集成到C#语言的基础上。借助于LINQ,查询现在已是高级语言构造,就如同类、方法和时间等。
对于编写查询的开发人员来说,LINQ最明显的“语言集成”部分是查询表达式。查询表示式是使用C#中引入的声明性查询语法编写的。通过使用查询语法,开发人员可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作,使用相同的基本查询表达式模式来查询和转换SQL数据库、ADO.NET
数据集、XML文档和流以及.NET集合中的数据等。
使用LINQ查询表达式时,需要注意一下几点:
①查询表达式可用于查询和转换来自任意支持LINQ的数据源中的数据。例如,单个查询可以从SQL数据库检索数据,并生成XML流作为输出。
②查询表达式容易掌握,因为它们使用许多常见的C#语言构造
③查询表达式中的变量都是强类型,但许多情况下不需要显示提供类型,因为编译器可以推断类型
④在循环访问foreach语句中的查询变量之前,不会执行查询
⑤在编译时,根据C#规范中设置的规则将插旬表达式转换为“标准查询运算符”方法调用。任何可以使用查询语法表示的查询都可以使用方法语法表示,但是多数情况下查询语法更易懂和简洁
⑥作为编写LINQ查询的一项规则,建议尽量使用查询语法,因此必须表示为方法调用
⑦一些查询操作,如Count或Max等,由于没有等效的查询表达式子句,因此必须表示为方法调用
⑧查询表达式可以变异为表达式目录树或委托,具体取决于查询所应用到的类型。其中,IEnumerable查询编译为委托,IQueryable和IQueryable查询编译为表达式目录树
LINQ查询表达式包含8个基本字句,分别为from、select、group、where、orderby、join、let和into,其说明如下:
子句 | 说明 |
---|---|
from | 指定数据源和范围变量 |
select | 指定当执行查询时返回的序列中的元素将具有的类型和形式 |
group | 按照指定的键值对查询结果进行分组 |
where | 根据一个或多个逻辑与和逻辑或运算符(&&或 ||)分隔的布尔表达式筛选源元素 |
orderby | 基于元素类型的默认比较器按升序或降序对查询结果进行排序 |
join | 基于俩个指定匹配条件之间的相等比较来连接来个数据源 |
let | 引入一个用于存储查询表达式中的子表达式结果的范围变量 |
into | 提供一个标识符,它可以充当对join、group或select子句的结果的引用 |
实例:
static void Main(string[] args)
{
string[] strLists = {
"编程词典", "C#编程词典", "C#程词典典藏版" };
IEnumerable<string> selectQuery =
from List in strLists
where List.IndexOf("C#") >= 0
select List;
foreach (string str in selectQuery)
{
Console.WriteLine(str);
}
Console.ReadLine();
}
效果:
2 使用LINQ操作SQL Server数据库
2.1 使用LINQ查询SQL Server数据库
使用LINQ查询SQL数据库时,首先要创建 LinqToSql类文件。创建LinqToSql类文件的步骤如下:
①在"解决方案资源管理器"窗口中选中当前项目,单击鼠标右键,在弹出的快捷菜单中选择"添加/添加新加项"命令。
②在"服务器资源管理器"窗口中连接SQL Server数据库,然后将指定数据库中的表映射到LinqDB.dbml中(可以将表拖拽到设计视图中)
③LinqDB.dbml文件将自动创建一个名称为LinqDBDataContext的数据上下文类,为数据库提供查询或操作数据库的方法,LINQ数据源创建完毕。LinqDBDataContext类中的数据均自动生成。
创建完LinqToSql类文件之后,接下来就可以使用它了。
实例:
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string ConStr = "Data Source=.;Initial Catalog=TJHIS;Integrated Security=True";
DataClasses1DataContext linq;
private void Form1_Load(object sender, EventArgs e)
{
}
private void BindInfo()
{
linq = new DataClasses1DataContext(ConStr);
if (comboBox1.Text == "")
{
var result = from info in linq.Student