LINQ代码实现大案例数据操作

上传人:e****s 文档编号:241653145 上传时间:2024-07-13 格式:PPT 页数:161 大小:1.15MB
返回 下载 相关 举报
LINQ代码实现大案例数据操作_第1页
第1页 / 共161页
LINQ代码实现大案例数据操作_第2页
第2页 / 共161页
LINQ代码实现大案例数据操作_第3页
第3页 / 共161页
点击查看更多>>
资源描述
第八章学习情境:LINQ代码实现大案例数据操作8.1学习情境引入8.2根本知识1:LINQ语法根底8.3根本知识2:LINQtoSQL8.4根本知识3:LINQtoDataSet8.5决策与方案8.6实施8.7检查与评价8.8训练8.1学习情境引入通过上两章的学习,我们已经根本掌握了进行管理信息系统数据访问的方法。通过VisualStudio.NET提供的ADO.NET组件和可视化组件,可以方便地读取或存储相应数据,并实现书店管理系统的各项功能。LINQ语言集成查询是VisualStudio2021和.NETFramework3.5版中一项突破性的创新,它提出了一种通过面向对象语法来实现对非面向对象数据源的查询技术,可查询的数据源从关系型数据库延伸到一般意义上的集合如数组和列表以及XML,代表着未来数据访问的开展方向。本章我们要利用LINQ技术来实现大案例的销售管理模块的数据访问。8.1学习情境引入8.1.1工程需求根据书店的日常业务分析,书店管理系统的销售管理模块主要有出库单填写、出库单管理、出库单打印等主要功能需求。1出库单填写顾客在购置图书后,书店的销售人员根据顾客所购图书情况,将出库单编号、购置单位、填单时间、经办人、是否付款、图书编号、售价、数量、金额等信息录入系统,生成出库单并通过出库单打印窗体进行打印。其中,出库单编号由系统自动生成;图书编号根据图书名称查询图书得到;售价根据定价和折扣率自动计算;金额根据售价和数量自动计算。8.1学习情境引入2出库单管理根据用户名和出库单的填单时间来查询出库单信息,并进行出库单信息管理如果有错误信息,且该出库单尚未执行出库操作,允许删除后重新填写)和打印功能。3出库单打印将用户填写的出库单信息或出库单管理中查询到的出库单信息以报表形式打印成纸质出库单。8.1学习情境引入8.1.2展示书店管理系统销售管理模块主要有出库单填写、出库单管理、出库单打印等功能窗体组成,实现了数据访问后的效果如图8-1、图8-2和图8-3所示。图图8-1 出库单填写窗体效果出库单填写窗体效果8.1学习情境引入图图8-2 出库单管理窗体效果出库单管理窗体效果图图8-3 出库单打印窗体效果出库单打印窗体效果8.1学习情境引入8.1.3技术分解在图8-2所示的出库单管理窗体中,出库单DataGridView控件中显示的是包括出库单ID、购置单位、填单时间、经办人等数据字段的出库单信息记录,出库单明细DataGridView控件中显示的是包括图书ID、折扣、售价、数量、金额等数据字段的出库图书明细,通过这些字段可以完整地描述图书出库单的信息。书店日常销售的图书数量可能成千上万,那么就会产生上万条这样的出库单记录,为了方便管理,通常将这些出库单记录和出库图书明细存放到数据库中。图8-2所示的窗体中显示的就是利用LINQtoSQL查询从数据库中查询得到的出库单信息记录和出库图书明细。8.1学习情境引入要利用LINQtoSQL查询技术从数据库中查询数据,需要建立用于映射数据库对象的实体类,并创立对象数据源,利用对象数据源和控件进行界面布局;在程序运行时,首先创立数据上下文DataContext对象,LINQtoSQL根据LINQ表达式或查询运算符生成SQL语句,发送到数据库进行操作;数据库返回后,LINQtoSQL负责将结果转换成实体类对象,并将实体类对象作为数据源绑定到显示控件。图8-2所示的出库单管理窗体中,查询得到的数据除了在窗体中显示外,必要时还要进行删除操作,然后再调用DataContext对象的SubmitChanges()方法将更新后的结果回写到数据库中。8.1学习情境引入利用LINQtoSQL查询技术,完全可以实现图8-1所示的出库单添加窗体的功能。另外,LINQtoDataSet将LINQ和ADO.NET集成,它通过ADO.NET获取数据,然后通过LINQ进行数据查询,从而实现对数据集DataSet进行非常复杂查询。图8-3所示的出库单打印窗体中就是用LINQtoDataSet查询技术实现的。因此,本章需要掌握的根本知识有:LINQ查询语法;LINQtoSQL查询;LINQtoDataSet查询。8.2根本知识1:LINQ语法根底8.2.1LINQ概述LINQ发音:Link的英文全称是LanguageIntegratedQuery,中文翻译为“语言集成查询,它是集成在.NET编程语言例如:C#、VB.NET等中的一种特性,目的是为.NETFramework提供更加通用和便利的信息查询方式,并且它对数据源提供了广泛的支持,而不仅仅局限于关系型数据库和XML。LINQ不仅允许查询表达式从富元数据、编译时语法检查、静态类型和智能感知这些已有的代码标准中受益,并且它同时还使得查询可以方便地对内存中的信息进行查询而不仅仅只是外部数据源。LINQ定义了一组标准查询操作符,应用于所有基于.NET平台的编程语言中。标准查询操作符允许查询作用于所有基于IEnumerable接口的数据源,并且它还允许自定义扩展操作符来扩大标准查询操作符集。LINQ查询架构如图8-4所示。8.2根本知识1:LINQ语法根底图图8-4 LINQ查询架构图查询架构图由图由图8-4可以看出,可以看出,LINQ包括包括5个局部:个局部:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。本章我们将。本章我们将着重介绍着重介绍LINQ to SQL和和LINQ to DataSets两局部。两局部。8.2根本知识1:LINQ语法根底8.2.2LINQ根本字句要用LINQ来编程,首先应学习由LINQ的字句和关键字以及按照查询语法组成的查询表达式。LINQ查询表达式的根本语法很容易掌握,它使用C#常见的语言构造,从外观看跟常用的关系型数据库查询语言SQL类似。LINQ查询表达式中的变量可以使用隐式类型局部变量,所以在构建LINQ查询表达式时,可以不用指定变量的类型。LINQ查询表达式中的作用就是从给定的一个或多个数据源中,按照指定条件查询数据,查询的结果可以按指定类型或表现形式返回。LINQ查询表达式包含如下8个上下文关键字,如表8-1所示。8.2根本知识1:LINQ语法根底关关 键键 字字说说 明明from指定数据源和范围变量where根据条件从数据源中筛选元素select指定查询结果中的元素所具有的类型或表现形式group对查询结果按照键值进行分组into提供一个标识符,它可以充当对join、group或 select字句结果的引用orderby对查询结果元素进行排序join按照指定的匹配条件来连接两个数据源let产生一个用于存储查询表达式中子表达式查询结果的范围变量表表8-1LINQ查询表达式关键字查询表达式关键字8.2根本知识1:LINQ语法根底先看一个最简单的LINQ查询表达式,体会一下它跟熟悉的SQL语句有什么不同。【例8-1】一个简单的LINQ查询表达式例子。首先启动VisualStudio.NET,创立一个名为ExampleLINQApplication的Windows应用程序工程。从工具箱拖放一个LIstBox和Button控件,并调整各控件的布局。在窗体布局设计完成后,双击Form1窗体的“查询按钮,在系统自动生成的“searchButton_Click事件中输入以下代码。privatevoidsearchButton_Click(objectsender,EventArgse)/构建内存数组作为数据源stringvalues=C语言程序设计,C#高级程序设计,软件工程,数据库;/构建LINQ查询表达式,查询名字中包含程序设计图书名称varvalueQuery=fromvalueinvalueswherevalue.IndexOf(程序设计)-1selectvalue;/用ListBox控件显示查询结果foreach(varvinvalueQuery)listBox1.Items.Add(v);8.2根本知识1:LINQ语法根底这样,一个简单的LINQ工程就算完成了,按F5编译并运行程序后,运行界面如图8-5所示。通过这个例如会发现,LINQ查询表达式跟SQL语句语法上一个明显的区别就是:LINQ查询表达式是以from子句开头,而不是象SQL语句那样使用select开头,并且LINQ查询表达式的结束必须是select子句或group子句。图图8-5 第第1个个LINQ工程运行界面工程运行界面8.2根本知识1:LINQ语法根底1from子句如果要构建一个LINQ表达式,就必须以from子句开头,用以指定数据源和范围变量。在【例8-1】的LINQ表达式的from子句中,value是范围变量,数组values是数据源。范围变量value的作用域是在当前的LINQ表达式,在这个LINQ表达式外的上下文中没有value这个变量。对于from子句中的范围变量value,如果没有指定数据类型,且数据源类型实现了IEnumerable接口,那么编译器会根据数据源的数据类型自动推断出value的数据类型,数据源仅仅实现了IEnumerable接口,那么需要指定value的数据类型。2where子句where子句在前面的例子总已经提到过,它是LINQ表达式的元素筛选机制,除了开始和结束的位置,它可以用在LINQ表达式的任意位置。在一个LINQ表达式中,可以有where子句,也可以没有;可以有一个where子句,也可以有多个。当有多个where子句时,它们之间的逻辑关系相当于逻辑“与,每个where子句可以包含一个或多个布尔逻辑表达式。多个表达式间用布尔运算符作分隔,例如逻辑“与、逻辑“或等。8.2根本知识1:LINQ语法根底【例8-2】查询名称中包含“程序设计且数量大于200的图书记录。privatevoidsearchButton_Click(objectsender,EventArgse)/构建List数据源ListbookList=newList()newBookInfoID=1,Name=C语言程序设计,Amount=330,newBookInfoID=2,Name=C#程序设计,Amount=300,newBookInfoID=3,Name=数据库程序设计,Amount=330,newBookInfoID=4,Name=软件工程,Amount=300;/查询名称中包含“程序设计且数量大于200的图书记录varbookQuery=frombookinbookListwherebook.Name.IndexOf(程序设计)-1&book.Amount200selectbook;/将结果显示到DataGridView控件中this.dataGridView1.DataSource=bookQuery.ToList();8.2根本知识1:LINQ语法根底工程完成以后,按F5编译并运行程序,运行界面如图8-6所示。图图8-6 图书查询窗体运行界面图书查询窗体运行界面8.2根本知识1:LINQ语法根底在此题中,用到了自定义的BookInfo数据类,具体定义如下。publicclassBookInfo/图书ID/publicintIDset;get;/图书名称/publicstringNameset;get;/数量/publicintAmountset;get;8.2根本知识1:LINQ语法根底3select子句LINQ表达式的查询结果,是使用select子句获得的。select子句获得的内容,取决于前面所有子句和其自身的表达式执行后的结果。最简单的select子句,就是直接输出from子句建立的那个范围变量。还可以只输出范围变量类型中的某个属性,或修改一下元素后再输出,总之,可以非常灵活地处理查询到的元素,得到想要的结果后再输出。【例8-3】将查询结果的字段名改为汉字。varbookQuery=frombookinbookListwherebook.Name.IndexOf(程序设计)-1&book.Amount200selectnew图书ID=book.ID,图书名称=book.Name,数量=book.Amount;8.2根本知识1:LINQ语法根底4group子句按照语法的规定,LINQ表达式必须以from子句开头,以select或group子句结束,所以除了使用select子句来返回结果外,也可以使用group子句来返回元素分组后的结果。分组查询在关系型数据库中是非常常见的一种操作,但在没有使用LINQ表达式以前,对内存对象进行分组查询是比较麻烦的一件事,现在,在LINQ表达式中只需使用group子句就可以轻松完成对内存对象的分组。【例8-4】将查询后结果按图书的数量分组。varbookQuery=frombookinbookListwherebook.Name.IndexOf(程序设计)-1&book.Amount200groupbookbybook.Amountintobookqselectbookq;8.2根本知识1:LINQ语法根底5into子句into子句作为一个临时标识符,用于group、select、join子句中,用以存储into子句之前的查询内容,使得后面的子句可以方便地使用into子句之前的查询内容,对其进行再次查询或排序、投影等操作。在【例8-4】中group子句中就应用了into子句。6排序子句LINQ可以按照元素的一个或多个属性对元素进行排序。LINQ表达式的排序方法分别为OrderBy、OrderByDescending、ThenBy、ThenByDescending等4种。OrderBy用于按照元素的值进行升序排序,OrderByDescending用于按照元素的值进行降序排序。ThenBy和ThenByDescending用于对元素进行次要排序。LINQ的排序子句中还有ascending关键字,它是升序关键字,默认可以省略。关键字后面可以有多个排序条件,每个条件用逗号分隔,ascending升序关键字、descending降序关键字可以跟任何条件进行一次或屡次匹配。8.2根本知识1:LINQ语法根底【例8-5】将查询后结果按图书的数量降序排列。varbookQuery=frombookinbookListwherebook.Name.IndexOf(程序设计)-1&book.Amount200orderbybook.Amountdescendingselectnew图书ID=book.ID,图书名称=book.Name,数量=book.Amount;8.2根本知识1:LINQ语法根底7let子句let子句用于在LINQ表达式中存储子表达式的计算结果。let子句创立一个范围变量用来存储结果,变量被创立后,不能被修改或赋值。此变量的作用域仅限于本LINQ表达式的后续子句中。【例86】let子句的应用。varbookQuery=frombookinbookListletb=book.Namewhereb.IndexOf(程序设计)-1&book.Amount200selectnew图书ID=book.ID,图书名称=b,数量=book.Amount;8.2根本知识1:LINQ语法根底8join子句join子句用于进行两个数据源的关联。如果一个数据源中元素的某个属性可以跟另外一个数据源的属性进行相等比较,那么这两个数据源那么可以用join子句进行关联。在LINQ表达式中使用equals关键字进行相等比较,而不是双等号=)。join子句用在多表联合查询中,后面的LINQtoSQL和LINQtoDataSet中会经常用到,在此就不再演示了。8.2根本知识1:LINQ语法根底8.2.3自测1填空题1LINQ包括5个组成局部,它们分别为:LINQtoObjects、LINQtoDataSets、_、LINQtoEntities、LINQtoXML。2LINQ查询表达式以_子句开头,必须是_子句或_子句结束。3在LINQ表达式中只需使用_子句就可以轻松完成对内存对象的分组。4LINQ表达式的排序方法分别为OrderBy、_、ThenBy、ThenByDescending等四种。5如果一个数据源中元素的某个属性可以跟另外一个数据源的属性进行相等比较,那么这两个数据源那么可以用_子句进行关联。在LINQ表达式中使用_关键字进行相等比较。8.3根本知识2:LINQtoSQL8.3.1向导创立实体类LINQtoSQL是LINQtoADO.NET的一局部,是.NETFramework3.5版的一个组件,它提供了用于将关系数据作为对象管理运行时所需的根底结构。使用LINQtoSQL时,需要首先建立用于映射数据库对象的模型,即实体类。在程序运行时,LINQtoSQL根据LINQ表达式或查询运算符生成SQL语句,发送到数据库进行操作。数据库返回后,LINQtoSQL负责将结果转换成实体类对象。LINQtoSQL的实体类,主要用于表示对象-关系映射ObjectRelationMapping,简称ORM。关系型数据库在各种应用中用来保存数据和建立数据之间的关系,在内存中建立一些对象来反映这些数据和它们之间的关系,一般将这些对象和相关的数据操作称为LINQ中间提供程序。LINQtoSQL与SQLServer之间的关系如图8-7所示。8.3根本知识2:LINQtoSQL图图8-7 LINQ to SQL对象模型对象模型如下图,如下图,LINQ to SQL通过操作中间提供程序来完成对数据库的操作,多数情况下无需程序通过操作中间提供程序来完成对数据库的操作,多数情况下无需程序员自己来编写员自己来编写SQL命令。表命令。表8-2概括了概括了LINQ to SQL对象与数据库对象的对应关系。对象与数据库对象的对应关系。LINQ to SQL对象模型对象模型关系数据模型关系数据模型实体类表类成员字段关联外键关系方法存储过程或函数表表8-2LINQ to SQL对象与数据库对象的对应关系表对象与数据库对象的对应关系表8.3根本知识2:LINQtoSQL1创立实体类在VisualStudio.NET中建立实体类的方式有多种,例如手动编码建立、使用XML文件映射、使用命令行工具SqlMetal生成、使用LINQtoSQL设计器等,其中最简单的方法就是使用LINQtoSQL设计器,下面我们就简要介绍此方式。首先启动VisualStudio.NET,创立一个名为ExampleLINQtoSQL的Windows应用程序工程。在“解决方案资源管理器中右键单击“ExampleLINQtoSQL节点,在快捷菜单中选择“添加项,在子菜单中单击“新建项如图8-8所示,翻开“添加新项对话框如图8-9所示。也可以通过菜单“工程的“添加组件子菜单来翻开“添加新项对话框。8.3根本知识2:LINQtoSQL 图图8-8 “解决方案资源管理器中右键单击解决方案资源管理器中右键单击“ExampleLINQtoSQL节点的快捷菜单节点的快捷菜单图图8-9 “添加新项对话框添加新项对话框在图8-9所示的“添加新项对话框中选中“LINQtoSQL类项,在名称栏中输入“BookStoreDataClasses.dbml后,单击“添加按钮,进入LINQtoSQL设计器。在LINQtoSQL设计器中,将book_Info表、in_Info表、in_Detail表、out_Info表、out_Detail表、stock_Info表和user_Info表从“效劳器资源管理器中拖入到设计视图中,如图8-10所示。保存“BookStoreDataClasses后,实体类就创立完成了。8.3根本知识2:LINQtoSQL图图8-10 LINQ to SQL设计器设计器2创立对象数据源单击“数据菜单的“添加新数据源项,翻开“数据源配置向导的“选择数据源类型对话框,如图8-11所示。在“数据源配置向导的“选择数据源类型对话框的中选择“对象类型后,单击“下一步按钮,翻开“数据源配置向导的“选择绑定对象对话框,如图8-12所示。8.3根本知识2:LINQtoSQL 图图8-11 “8-11 “数据源配置向导的数据源配置向导的“选择数据源类型对话框选择数据源类型对话框8.3根本知识2:LINQtoSQL图图8-12 “数据源配置向导的数据源配置向导的“选择绑定对象对话框选择绑定对象对话框在“数据源配置向导的“选择绑定对象对话框中单击“ExampleLINQtoSQL节点前面的“+号,再单击“ExampleLINQtoSQL节点前面的“+号,选择“book_Info项后,单击“下一步按钮,翻开“数据源配置向导的“添加对象数据源对话框,如图8-13所示。在“数据源配置向导的“添加对象数据源对话框中单击“完成按钮,即可完成“book_Info对象数据源的创立,创立好的对象数据源图8-14所示。8.3根本知识2:LINQtoSQL图图8-13 “数据源配置向导的数据源配置向导的“添加对象数据源添加对象数据源对话框对话框8.3根本知识2:LINQtoSQL图图8-14 “book_Info对象数据源对象数据源同样的步骤,我们可以创立同样的步骤,我们可以创立in_Info对象数据源、对象数据源、out_Info对象数据源、对象数据源、stock_Info对象数据源和对象数据源和user_Info对象数据源。创立完成后数据源如图对象数据源。创立完成后数据源如图8-15所示。所示。对象数据源创立完成后,我们就可以应用对象数据源来编写数据应用访问程序。下对象数据源创立完成后,我们就可以应用对象数据源来编写数据应用访问程序。下面做一个简单的图书信息管理窗口,来实现对图书信息的管理。面做一个简单的图书信息管理窗口,来实现对图书信息的管理。【例8-7】LINQ实现图书信息管理。在“数据源面板中选中“book_Info节点,拖到Form1窗体中,调整窗体中控件布局,如图8-16所示。完成窗体中控件布局后,右键单击窗体空白处,选择“查看代码菜单项,进入代码编辑窗口。在代码编辑窗口中输入如下代码,实现对实体类的初始化。8.3根本知识2:LINQtoSQL图图8-15 多个对象数据多个对象数据源源 图图8-16 窗体控件布局窗体控件布局8.3根本知识2:LINQtoSQLpublicpartialclassForm1:Form/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();publicForm1()InitializeComponent();然后在窗体的Form_Load事件中,为DataGridView控件来绑定数据源。步骤为双击窗体空白处,在自动生成的Form1_Load事件代码区,输入以下代码。8.3根本知识2:LINQtoSQLprivatevoidForm1_Load(objectsender,EventArgse)/为DataGridView控件来绑定数据源this.book_InfoDataGridView.DataSource=bookstore.book_Info;/为BindingNavigator控件来绑定数据源BindingSourcebds=newBindingSource();bds.DataSource=this.bookstore.book_Info;this.book_InfoBindingNavigator.BindingSource=bds;在BindingNavigator控件中,选中“保存工具按钮,将其Enabled属性设置为True,并为其Click事件增加如下代码。privatevoidbook_InfoBindingNavigatorSaveItem_Click(objectsender,EventArgse)bookstore.SubmitChanges();这样,一个简单的图书信息管理窗口就完成了,按F5编译并运行程序后,运行界面如图8-17所示。8.3根本知识2:LINQtoSQL图图8-17 图书信息管理运行界面图书信息管理运行界面8.3根本知识2:LINQtoSQL3DataContext类在LINQtoSQL中,DataContext类负责内存对象和数据库之间的数据交换和其他数据操作,还负责把数据库中数据映射成实体类的实例。通过DataContext对象,可以方便地连接数据库、执行SQL命令、跟踪实体对象状态。1常用构造函数DataContextIDbConnection):通过引用由.NETFramework使用的连接来初始化DataContext类的一个新实例。DataContextString):通过引用文件源来初始化DataContext类的一个新实例。2常用属性Log将SQL查询或命令显示到TextReader。【例8-8】通过Log属性查看LINQ的操作的SQL命令。在ExampleLINQtoSQL工程中,新建Form2窗体,从“工具箱内拖假设干控件到Form2窗体,并调整各控件布局如图8-18所示。8.3根本知识2:LINQtoSQL图图8-18 操作日志查看窗体布局操作日志查看窗体布局8.3根本知识2:LINQtoSQL完成窗体布局后,双击“查找按钮,在系统自动生成的“searchButton_Click事件中输入以下代码。privatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContext对象BookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/在D盘根目录下建立log.tx文件,存储操作日志StreamWritersw=newStreamWriter(d:log.txt,true);bookstore.Log=sw;varbookQuery=frombfinbookstore.book_Infowherebf.图书名称.IndexOf(searchTextBox1.Text)-1|bf.作者.IndexOf(searchTextBox1.Text)-1|bf.出版社.IndexOf(searchTextBox1.Text)-1selectbf;this.book_InfoBindingSource.DataSource=bookQuery;sw.Flush();sw.Close();/读取log.tx文件所存储操作日志StreamReadersr=newStreamReader(d:log.txt);this.textBox1.Text=sr.ReadToEnd();sr.Close();在工程的Program.cs文件中,将启动窗体改为Form2后,按F5编译并运行程序,运行界面如图8-19所示。8.3根本知识2:LINQtoSQL图图8-19 操作日志查看窗体运行界面操作日志查看窗体运行界面8.3根本知识2:LINQtoSQL3常用方法CreateDatabase:在效劳器上创立数据库。DatabaseExists:检测数据库是否存在。DeleteDatabase:删除由DataContext映射的数据库。SubmitChanges:提交数据库的更改。ExecuteQuery:直接对数据库执行SQL查询。ExecuteCommand:直接对数据库执行SQL命令。ExecuteQuery方法和ExecuteCommand方法作为在LINQtoSQL缺乏以应对的特定方案的时刻而存在。8.3根本知识2:LINQtoSQL【例8-9】创立SQLServerExpress数据库文件。/指定需要创立的数据库文件名stringfliename=d:LINQTestDatabase.mdf;/初始化数据上下文DataContextBookStoreDataClassesDataContextbookStore=newBookStoreDataClassesDataContext(fliename);/检测数据库是否存在,假设存在,那么删除if(bookStore.DatabaseExists()bookStore.DeleteDatabase();/创立据库bookStore.CreateDatabase();8.3根本知识2:LINQtoSQL【例8-10】将图书信息表中?小型网的组建与应用?的出版社改为人民邮电出版社。/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/查询?小型网的组建与应用?记录varbookQuery=frombfinbookstore.book_Infowherebf.图书名称=小型网的组建与应用selectbf;/修改if(bookQuery.Count()=1)bookQuery.First().出版社=人民邮电出版社;/提交修改bookstore.SubmitChanges();8.3根本知识2:LINQtoSQL8.3.2LINQtoSQL查询LINQ查询运算是依靠一组扩展方法来实现的,这些扩展方法分别在System.Linq.Enumerable和System.Linq.Queryable两个静态类中,它们是泛型IEnumerable接口和泛型IQueryable接口的实现类型。Enumerable类的扩展方法主要用来操作内存对象,采用线性流程,每个运算符按顺序先后执行。Queryable类的扩展方法主要用来操作关系型数据库这种数据源,在执行时,先把LINQ表达式分解成表达式目录树,LINQ提供程序就可以根据表达式目录树来生成关系数据库查询语句,即SQL命令,然后进行相关操作。因此,Enumerable类和Queryable类的扩展方法根本相同。根据每个查询运算符的执行行为不同,大致可分为立即执行和延期执行两类。延期执行的运算符将在枚举元素时被执行,这一点在编程时需特别留意。8.3根本知识2:LINQtoSQL1用于延期执行的方法1Take方法。Take方法用于从一个从序列的开头返回指定数量的连续元素,其常用方法原型如下。publicstaticIQueryableTake(thisIQueryablesource,intcount)TSource:序列中元素的类型。source:要返回元素的序列。count:要返回的元素数量,如果小于0返回空序列;如果大于序列中的元素总数,那么返回全部元素。Take方法也可以被IQueryable(Of)类型的任何实例对象来使用。当作为实例方法来调用时,只需提供count参数的值即可。【例8-11】查询图书销售记录表出库单中金额最大的5条记录。翻开上一节创立的ExampleLINQtoSQL的Windows应用程序工程,通过“工程菜单的“添加新项子菜单来新建Form3窗体,从“数据源中拖“out_Info节点到Form3窗体,并从“工具箱中拖假设干控件到Form3窗体,各控件布局如图8-20所示。8.3根本知识2:LINQtoSQL图图8-20 查询图书销售记录中金额最大的查询图书销售记录中金额最大的5条记录的窗体条记录的窗体布局布局8.3根本知识2:LINQtoSQL完成窗体布局后,双击“查询按钮,翻开代码编辑器。在系统自动生成的“searchButton_Click事件中输入以下代码。privatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/构建LINQ查询表达式varbookQuery=fromoutfinbookstore.out_Infoorderbyoutf.金额descendingselectoutf;/绑定数据源,并取得数据的前5条记录this.out_InfoDataGridView.DataSource=bookQuery.Take(5);/填充比照DataGridViewthis.out_InfoDataGridView2.DataSource=bookQuery;在工程的Program.cs文件中,将启动窗体改为Form3后,按F5编译并运行程序,运行界面如图8-21所示。8.3根本知识2:LINQtoSQL图图8-21 查询图书销售记录中金额最大的查询图书销售记录中金额最大的5条记录的运行条记录的运行窗体窗体8.3根本知识2:LINQtoSQL跟Take方法类似的还有TakeWhile方法,用于根据条件来获取序列中的局部元素。该方法在执行时,从序列的第一个元素开始比较,只要遇到不符合条件的元素,就会立即停止比较。2Skip方法。Skip方法用于跳过序列中从开头算起的指定数量的元素,然后返回剩余的元素,其常用方法原型如下。publicstaticIQueryableSkip(thisIQueryablesource,intcount)8.3根本知识2:LINQtoSQLTSource:序列中元素的类型。source:要返回元素的序列。count:返回剩余元素前要跳过的元素数量,如果大于等于序列中的元素总数,那么返回空序列;如果小于序列中的元素总数,那么返回第count条以后的算有元素。Skip方法也可以被IQueryable(Of)类型的任何实例对象来使用。当作为实例方法来调用时,只需提供count参数的值即可。跟Skip方法类似的还有SkipWhile方法,用于跳过序列中满足指定条件的元素,返回剩余的元素。Take、TakeWhile、Skip、SkipWhile这4个方法,用于返回序列中的局部元素,它们之间互为补充关系。灵活运用这4个方法,可以非常方便地对查询结果进行分页处理。8.3根本知识2:LINQtoSQL3Distinct方法。Distinct方法用于获取序列中不重复的元素,也就是过滤掉序列中的重复元素,其常用方法原型如下。publicstaticIQueryableDistinct(thisIQueryablesource)TSource:序列中元素的类型。source:要返回元素的序列。Distinct方法也可以作为实例方法来调用,在调用时须省略source参数。【例8-12】查询仓库中还有库存的图书名称。解析:在书店管理系统中,书店每采购一批图书,系统就向库存表中插入一条库存记录。这样,在库存表中,就算是同一种图书,也因为采购的批次不同而保存在不同的记录中。因此,查询仓库中有库存的图书名称时,须用到Distinct方法过滤掉重复元素。8.3根本知识2:LINQtoSQLprivatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/构建LINQ查询表达式varbookQuery=fromstockfinbookstore.stock_Infojoinbfinbookstore.book_Infoonstockf.图书IDequalsbf.图书IDselectbf.图书名称;/将结果显示到ListBox控件中this.图书名称ListBox.DataSource=bookQuery.Distinct();8.3根本知识2:LINQtoSQL4Union方法。Union方法用于合并两个序列,合并时去掉重复元素,其常用方法原型如下。publicstaticIQueryableUnion(thisIQueryablesource1,IEnumerablesource2)TSource:输入序列中的元素的类型。source1:要合并的第一个元素序列,source2:要合并的第二个元素序列。Union方法也可以作为实例方法来调用,在调用时须省略source1参数。8.3根本知识2:LINQtoSQL【例8-13】合并两个数组并去掉重复元素。/构建两个数组,并赋值intints1=5,3,9,7,5,9,3,7;intints2=8,3,6,4,4,9,1,0;/调用Union方法来合并两数组,结果赋值给ints3数组IEnumerableints3=ints1.AsQueryable().Union(ints2);/将结果显示到ListBox控件中foreach(intiinints3)this.listBox1.Items.Add(i.ToString();上例中,两个数组合并后,ints3数组的值为:5397864108.3根本知识2:LINQtoSQL另外常用的处理两个序列的方法还有:Concat方法用于连接两个序列,与Union方法不同之处是在合并时不会过滤掉重复元素;Intersect方法用于生成两个序列的交集,也就是把两个序列中相同的元素提取出来,建立一个新的序列;Except方法用于生成两个序列的差集,也就是从第一个序列中找出不同于第二个序列中所有元素的元素,组成一个新序列。8.3根本知识2:LINQtoSQL2用于立即执行的方法1First方法。First方法用于返回序列中的第一个元素,其函数原型如下。publicstaticTSourceFirst(thisIQueryablesource)或publicstaticTSourceFirst(thisIQueryablesource,ExpressionFuncpredicate)8.3根本知识2:LINQtoSQLTSource:序列中元素的类型。source:要返回元素序列,predicate是用于测试每个元素是否满足条件的函数,一般用Lambda表达式来构建。First方法也可以作为实例方法来调用,在调用时须省略source参数。First方法查询返回的类型是一个的Review对象,允许直接访问其属性。这一点,在以后LINQtoSQL数据更新时经常用到。【例8-14】查询某时间段内第一单金额过千的销售记录。在ExampleLINQtoSQL工程中,新建Form6窗体,从“工具箱内拖假设干控件到Form6窗体,窗体的控件布局如图8-22所示。8.3根本知识2:LINQtoSQL图图8-22 查询某时间段内第一单金额过千的销售记录查询某时间段内第一单金额过千的销售记录窗体布局窗体布局8.3根本知识2:LINQtoSQL完成窗体布局后,双击“查询按钮,在系统自动生成的“searchButton_Click事件中输入以下代码。privatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/构建LINQ查询表达式DateTimebtime=dateTimePicker1.Value;DateTimeetime=dateTimePicker2.Value;varbookQuery=fromoutfinbookstore.out_Infowhereoutf.填单时间=btime&outf.填单时间1000selectoutf;/取得查询数据的第1条记录,并填充各控件textBox1.Text=bookQuery.First().经办人.ToString();textBox2.Text=bookQuery.First().金额.ToString();textBox3.Text=bookQuery.First().填单时间.ToString();/填充比照控件内容this.out_InfoDataGridView.DataSource=bookQuery;在工程的Program.cs文件中,将启动窗体改为Form6后,按F5编译并运行程序,运行界面如图8-23所示。8.3根本知识2:LINQtoSQL图图8-23 查询某时间段内第一单金额过千的销售记录窗体运查询某时间段内第一单金额过千的销售记录窗体运行界面行界面跟跟First方法类似的还有方法类似的还有FirstOrDefault方法,它也是用于返回序列的第一个方法,它也是用于返回序列的第一个元素。二者不同之处在于,使用元素。二者不同之处在于,使用FirstOrDefault方法如果未找到元素,返回元方法如果未找到元素,返回元素类型的默认值,而素类型的默认值,而First方法那么报错。方法那么报错。8.3根本知识2:LINQtoSQL2Last方法。Last方法用于返回序列中的最后一个元素,其函数原型如下。publicstaticTSourceLast(thisIQueryablesource)或publicstaticTSourceLast(thisIQueryablesource,ExpressionFuncpredicate)TSource:序列中元素的类型。source:要返回元素序列,predicate是用于测试每个元素是否满足条件的函数,一般用Lambda表达式来构建。8.3根本知识2:LINQtoSQLLast方法也可以作为实例方法来调用,在调用时须省略source参数。Last方法查询返回的类型是一个的Review对象,可以直接使用其属性。跟Last方法类似的还有LastOrDefault方法,它也是用于返回序列的最后一个元素。二者不同之处在于,使用LastOrDefault方法如果未找到元素,返回元素类型的默认值,而Last方法那么报错。3Count方法。Count方法用于返回序列中元素的数量,返回值是一个System.Int32型数据,其常用方法原型如下。publicstaticintCount(thisIQueryablesource)Count方法也可以作为实例方法来调用,在调用时须省略source参数。8.3根本知识2:LINQtoSQL【例8-15】统计书店本月的交易卖出次数。在ExampleLINQtoSQL工程中,新建Form8窗体,从“工具箱内拖假设干控件到Form8窗体,并调整各控件布局。完成窗体布局后,双击“查询按钮,在系统自动生成的“searchButton_Click事件中输入以下代码。8.3根本知识2:LINQtoSQLprivatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();/构建LINQ查询表达式DateTimebtime=dateTimePicker1.Value;DateTimeetime=dateTimePicker2.Value;varbookQuery=fromoutfinbookstore.out_Infowhereoutf.填单时间=btime&outf.填单时间=etime.AddDays(1)selectoutf;/调用Count()取得查询数据的数目,并填充textBox1.Text=bookQuery.Count().ToString();/填充比照控件内容this.out_InfoDataGridView.DataSource=bookQuery;8.3根本知识2:LINQtoSQL在工程的Program.cs文件中,将启动窗体改为Form8后,按F5编译并运行程序,运行界面如图8-24所示。跟Count方法类似的是LongCount方法,它也用于返回序列中元素的数量,只不过LongCount方法返回值是一个System.Int64型数据。4Sum方法。Sum方法用于计算数值序列之和。Sum方法有20个方法原型,可以直接对Decimal、Double、Int32、Int64、Single这几个类型的序列求和;也可用于以上数据类型的可空序列求和;也可使用转换函数将任意类型的序列转换为Decimal、Double、Int32、Int64、Single类型来求和。Sum的常用方法原型如下。8.3根本知识2:LINQtoSQL图图8-24 统计书店本月的交易卖出次数窗体运行界面统计书店本月的交易卖出次数窗体运行界面8.3根本知识2:LINQtoSQLpublicstaticNullableSum(thisIQueryableNullablesource)TSource:序列中元素的类型。TResult:可以是Decimal、Double、Int32、Int64、Single类型之一。source:要计算和的可以为null的TResult类型值序列。Sum方法的返回值是类型为TResult的序列元素之和。【例8-16】统计本月的销售额。在ExampleLINQtoSQL工程中,新建Form9窗体,从“工具箱内拖假设干控件到Form9窗体,并调整各控件布局。完成窗体布局后,双击“查询按钮,在系统自动生成的“searchButton_Click事件中输入以下代码。8.3根本知识2:LINQtoSQLprivatevoidsearchButton_Click(objectsender,EventArgse)/初始化数据上下文DataContextBookStoreDataClassesDataContextbookstore=newBookStoreDataClassesDataContext();DateTimebtime=dateTimePicker1.Value;DateTimeetime=dateTimePicker2.Value;/构建LINQ查询表达式varsumQuery=fromoutfinbookstore.out_Infowhereoutf.填单时间=btime&outf.填单时间=btime&outf.填单时间=etime.AddDays(1)selectoutf;this.out_InfoDataGridView.DataSource=bookQuery;在工程的Program.cs文件中,将启动窗体改为Form9后,按F5编译并运行程序,运行界面如图8-25所示。与Sum方法类似的还有Average方法、Min方法、Max方法,可以用来对序列进行统计。Average方法用来计算数值序列的平均值,Min方法用来获取序列的最小值,Max方法用来获取序列的最大值。8.3根本知识2:LINQtoSQL图图8-25 本月销售额统计窗体运行界面本月销售额统计窗体运行界面8.3根本知识2:LINQtoSQL8.3.3LINQtoSQL更新在LINQtoSQL中,DataContext类负责内存对象和数据库之间的数据交换和其他数据操作,还负责把数据库中数据映射成实体类的实例。通过DataContext对象,可以方便地连接数据库、执行SQL命令、跟踪实体对象状态。数据库表格的结构、行数据由实体类进行映射,而表格记录集用Table来表示。Table是一个泛型集合类,它的元素就是表格实体对象。它提供一组方法,对元素进行增加、删除等更新操作,并通过DataContext将这些操作影响到数据库表格。8.3根本知识2:LINQtoSQL1Table类Table是一个泛型集合类,它提供一组方法,对元素进行增加、删除等更新操作,并通过DataContext类将这些操作影响到数据库表格。1InsertOnSu
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业管理 > 商业计划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!