2023年12月30日发(作者:)
第十五章 Microsoft .NET 框架的版本
在本章中,首先概括地回顾了.NET框架的几个重要版本,然后重点介绍了在.NET框架的较新版本中常用的Entity Framework 和LINQ技术,它们在.NET Framework 3.5中首次出现。
15.1 .NET 框架各种版本概览
截止到现在,微软共发布了.NET Framework 1.0、.NET Framework 1.1、.NET Framework 2.0、.NET
Framework 3.0、.NET Framework 3.5、.NET Framework 4.0。.NET Framework 4.5也正在测试阶段,估计即将发布。.NET Framework 2.0是较早的一个版本,但已经相当成熟。本书前面章节中介绍的内容基本上都适用于.NET Framework 2.0以及与之配套的Visual Studio 2005。在本节,我们将对.NET Framework 3.0以上版本做一些介绍。
15.1.1 .NET Framework 1.0
.NET Framework 1.0发布于2002年2月,该版本一年之后就被.NET Framework 1.1代替。.NET Framework
1.1(版本号1.1.4322)和Visual 2003一起隆重登场,为应用程序开发者提供了全新的开发工具和环境。
15.1.2 .NET Framework 2.0
.NET Framework 2.0(版本号2.0.50727)发布于2005年11月,与其配套的Visual Studio版本是Visual
Studio 2005。.NET Framework 2.0修正了.NET Framework 1.0中暴露的一些问题并增加了一些新的功能,这是一个相当成熟、稳定和容易扩展的版本。Visual Studio 2005与Visual Studio 2003比较,也有明显的变化,例如代码编辑器具有更强的智能感应功能,能即时提示符合当前上下文的各种名称和符号。
15.1.3 .NET Framework 3.0
.NET Framework 3.0,曾用名为“WinFX”,它的发布日期为2006年11月。该版本依然使用.NET
Framework 2.0的公共语言运行库(CLR),但加入了适应未来软件发展方向的4个 Framework :
(1) Windows Presentation Foundation(WPF)
WPF提供更佳的用户体验,可用来开发Windows Forms程序以及浏览器应用程序。
(2) Windows Communication Foundation(WCF)
用于提供支持SOA(面向服务的软件构架)的安全的网络服务(Web Service)Framework 。
(3) Windows Workflow Foundation(WF)
可提供一个设计与发展工作流程导向(Workflow-oriented)应用程序基础支持的应用程序接口。
(4) Windows CardSpace
这是一组代号为CardSpace的Windows新功能,可提供一种基于标准的解决方案,用于使用和管理不同的数字标识。
15.1.4 .NET Framework 3.5
.NET Framework 3.5发布于2007年11月。这是一个具有重要意义的版本,因为它是随Visual Studio 2008
一起发布的。
.NET Framework 3.5中主要新增了对LINQ(Language-Integrated Query,语言集成查询)、(Entity
Framework, 实体框架)、EDM (实体数据模型) 和对SQL Server 2008的数据提供程序的支持。同时,该版本还包含了.NET Framework 2.0 SP1以及.NET Framework 3.0 SP1,可用于为这两个版本提供安全性修复。
此外此版本提供的新功能还有:
扩展方法(Extension Method)属性(Attribute),用于为扩展方法提供LINQ支持。
表达式目录树(Expression Tree),用于为Lambda表达式提供支持与语言集成查询 (LINQ)和数据感知紧密集成。
对用于生成WCF服务的全新Web协议支持,包括AJAX、JSON、REST、POX、RSS、ATOM和若干新的WS-*标准等。
为WPF增加的功能包括对业务线应用程序的更好支持、本机闪屏支持、DirectX像素着色器支持以及新的WebBrowser控件。对WPF的性能改进包括启动速度的位图效果性能的提高等。
新增的ASP .NET功能包括ASP .NET动态数据和ASP .NET AJAX附加功能,前者提供了无需编写代码就可实现数据驱动的快速开发的丰富支架 Framework ,后者为管理浏览器历史记录提供了支持。
数据平台,此平台提供了ADO .NET Entity Framework、实体数据模型 (EDM) 、LINQ to
Entities、Entity SQL、ADO .NET数据服务及实体数据模型工具等。可使开发人员能够针对概念性实体数据模型进行编程,从而减轻他们的编码和维护工作。
15.1.5 .NET Framework 4.0
.NET Framework 4.0于2010年4月12日正式推出。与此同时,Visual Studio 2010也隆重登场。此版本中主要增加了并行支持、企业级 .NET提供的独立开发平台、自带高度安全的网络系统等,并且更加倚重软件组件以及组件导向程序,以致于可以完全取代COM。
15.1.6 .NET Framework 版本兼容性问题
.NET Framework 提供高度的向后兼容性支持。这意味着使用 .NET Framework 的较早版本创建的应用程序可以在更高的版本上运行。例如,大多数使用 1.0 版创建的应用程序将在 2.0或更高版本上运行。在Visual 下创建的项目,在较高的版本下打开时,一般会要求进行版本转换。这种转换大部分是自动进行的,转换成功后即能在高版本下正常运行。但这种转换不是100%可以成功的。
.NET Framework 一般不支持向前兼容性。即.NET Framework较高版本创建的应用程序一般不能够在较早的版本下运行。
15.2 EF基础知识
Entity Framework技术最早在.NET Framework 3.5中出现,可用来支持更好地对储存在关系型数据库表中的实体对象进行封装。
15.2.1 Entity Framework概述
Entity Framework缩写为EF,可翻译为实体框架,是微软中的一组支持开发面向数据的软件
应用程序的技术。长久以来面向数据的应用程序的架构师和开发人员曾为实现两个迥然不同的目标费尽心机:他们必须为要解决的业务问题的实体、关系和逻辑构建模型,还必须处理用于存储和检索数据的数据引擎。数据可能跨多个各有不同协议的存储系统;甚至使用单个存储系统的应用程序也必须在存储系统的要求与编写高效且容易维护的应用程序代码之间取得平衡。因此, Entity Framework技术由此应运而生。
实体框架 使开发人员可以采用特定于域的对象和属性的形式使用数据,而不必自己考虑存储这些数据的基础数据库表和列。通过提升开发人员在处理数据时可以使用的抽象级别并减少创建和维护面向数据的应用程序所需的代码,可以实现这一目的。实体框架 是 .NET Framework 3.5中新增的,可以在安装了 .NET Framework 3.5 Service Pack 1 (SP1) 的任何计算机上运行。实体框架中用到的类主要位于、、s等命名空间。
15.2.2
EF映射和SSDL、CSDL、MSL
Entity Framework提供了把数据库映射到实体的三层映射的办法,这三层映射是:
逻辑层:该层用于定义关系数据,使用的语言是SSDL(Store Schema definition Language,存储架构定义语言)
概念层:该层用于定义.NET中的类,使用的语言是CSDL(Conceptual Schema Definition Language,概念架构定义语言)
映射层:该层用于定义从.NET 类到关系表间的映射,使用的语言是MSL(Mapping Specification
Language,映射规范语言)
在三层映射下,存储模型是特定于提供程序的,因此可以在各种数据源之间使用一致的概念模型。实体框架使用这些模型和映射文件将对概念模型中的实体和关系的创建、读取、更新和删除操作转换为数据源中的等效操作。 实体框架甚至还支持将概念模型中的实体映射到数据源中的存储过程。
使用visual (2008或以上版本)中设计器可设计实体类及其关系,再把它们映射到数据库。也可以通过系统提供的向导从关系型数据库导出(自动转换)EF映射,系统会生成相应的SSDL、CSDL或MSL文档。然后依照三层映射关系就能自动创建实体类供.NET应用程序中使用。程序员完全不必手写任何有关的文档。
下面通过一个简单的示例,介绍如何在EF有关向导指引下,建立数据库应用程序的过程。
【例15-1】我们以一个常见的有关学生成绩管理的数据库为例,该数据库中包含tblCourse、tblScore、tblStudent等几个数据表。在EF下,我们可不必关心具体的数据库管理系统。图15-1为在IDE下观察到用该数据库建立的数据源。
图15-1
数据源中包含的tblCourse、tblScore、tblStudent
在Visual Studio 2008下创建一个解决方案解决方案SolutionDemo,再新建一个类库DataEntities,可删除由自动生成的文件。
为了在解决方案中导入EF,请按以下步骤进行:
(1) 在解决方案资源管理器中执行“添加”->“新建项”,在“添加新项”对话框中选择实体数据模型,再单击“添加”按钮完成添加,如图15-2所示:
图15-2选择实体数据模型模板
注: 3.5 Entity Framework 实体框架是在.NET Framework 3.5 SP1中引入的,因此有些VS 2008系统中,上述 实体数据模型的模板不会在图15-2显示的对话框中出现。此时,可设法对系统补充安装相关组件或设法在安装光盘中找到WCUEFTools目录下ADONETEntityFrameworkTools_这个文件并将其安装就可以了。网上也可下载到用于单独安装该模板的有关组件和程序的打包文件。
(2) 在“实体数据模型”的向导下配置数据源,在图15-3中选择“从数据库生成”,然后执行“下一步”。
当出现图15-6时,填写服务器名称,登录方式和选择数据库。
图15-3 选择从数据库生成EF对象的模式
(3) 按系统提示对数据源进行配置。包括填写服务器名称、登录方式、选择数据库等;然后还要选择映射范围,即在新建的数据源中选择数据库表、视图或存储过程等对象。该步骤完成后如图15-4所示:
图15-4在向导下选择数据库表
(4) 单击“完成”,结束向导。此时,系统根据已选择的映射范围自动生成全部有关配置文档。配置的结果保存在该类库的文件夹内。其中有一个Entity Framework的配置文件,用于记载数据库的连接
信息;还有一个扩展名为.edmx的文件,图15-5为在系统下将该Edmx文件作为XML打开 时的画面:
图15-5 系统生成与选定数据库相关.edmx的文件
从中可看出,在作为根元素的 edmx:Runtime下一层的三个元素为 edmx:StorageModels、edmx:ConceptualModels和 edmx:Mappings。展开这三个元素,可以分别获取采用SSDL、CSDL和MSL描述的EF中三个映射层的信息。
以下是本例中 edmx:Mappings 元素包含的映射层信息:
xmlns="/ado/2008/09/mapping/cs"> CdmEntityContainer="dbSSCEntities">
其中的内容是用MSL表示的,但基本上都可以直接看明白的。SSDL、CSDL写的内容同样也是容易被理解的。因此,必要时也可手写修改Edmx文件或编撰完整的Edmx文件。
(5) 在IDE下对该类库项目执行“生成”,系统会按照Edmx中描述,生成相关实体类的代码并编译。这些类隔离了数据库相关的操作,可供此解决方案中其它项目中应用。
15.2.3 EF实体类对象的操作
数据实体映射将数据库中储存的数据转换为程序中使用的对象,可使程序的注意力从关注数据库操作转移到实体间的关系和互操作。在示例15-1中,利用向导已将有关的数据库转换在相关问题中便于处理的实体,在下面的几个示例中,我们将说明如何对这些实体对象进行操作。
【例15-2】在VS 2008下打开在示例15-1中创建的解决方案SolutionDemo,在该解决方案下新建一个网站,在网站中添加对类库DataEntities的引用。
在默认的主页中添加一个GridView控件用于显示与实体对象相关的信息,相应的前台
代码为:
以下为包含在中的后台程序代码:
…
private ntities ds = new dbSSCEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack){
LoadData();
}
}
private void LoadData()
{
List
if (stus != null && > 0){
urce = stus; //将List中德数据绑定到数据显示控件上
nd();
}
else{
ataText = "NO any data, Please load again!";
}
}
当通过浏览器访问该Web页面时,GridView中显示的内容如图15-6所示:
图15-6浏览tblStudent的数据
说明:
(1) ntities 包含从数据库转换得到的所有类型(tblStudent等实体类)。List
(2) 因为原数据库中性别字段为布尔型,转换后就显示为 true或 false。如果要显示为“男”或“女”,可以对 GridView做一些设置。
也可以对dbSSCEntities中定义的实体对象和集合进行添加、删除和修改等操作。
【例15-3】本例对实体对象进行添加。和之前一样,在解决方案下新建一个网站并添加对DataEntities的引用。
参照图15-7在设计视图下设计主页的界面,在文件中输入以下代码:
图15-7在该界面下添加记录
protected void btnAddStudent_Click(object sender, EventArgs e)
{
…
dent stu = new dent();
= strStID;
= strStName;
if(strStSex=="男")
= true;
else
= false;
e = strStPhone;
lScore = 16(strStTotalScore);
strAddResult = AddStudent(stu);
…
}
private string AddStudent(tblStudent student)
{
string strResult = ;
if (student != null){
try{
ntities de = new dbSSCEntities();
if (rDefault(c => == ) == null){
(student);
anges();
strResult = "Add Student Successfully";
}
}
catch (Exception ex){
strResult = "faild to Add Student, please try again";
}
}
return strResult;
}
说明:
(1) 在添加的时候,EDMX中的字段对应关系要和数据库中一致,否则会出错。错误信息一般提示为实体的属性错误。
(2) 代码中出现的 c => ,是lamda表达式的写法,在.NET中可视为一种特殊的委托。此处实际的作用是表示选择student表中id等于的所有记录。
(3) 这里需要理解的是,将数据作为一个实体添加进入数据库,这里很多朋友要问,怎么把实体类添加到数据库呢,这里却什么SQL语句都没有。这就是Entity Framework的伟大之处了,做为程序员,不需要了解数据库具体的执行过程, Entity Framework已经为我们做好一切,我们也不用担心 SQL注入等安全问题,只用把注意力放在业务逻辑上即可。
在做删除时,和添加操作相似,也是只需对实体类操作即可。请看以下示例:
【例15-4】在解决方案下新建一个网站并添加对DataEntities的引用。参照图15-8设计主页面,在文件中输入以下代码:
图15-8 在该界面下删除记录
„
ntities de = null;
List
int tempStudentID = 0;
protected void btnDeleteStudent_Click(object sender, EventArgs e)
{
de = new ntities();
int tempID=16(edValue);
dent stu
= rDefault(c => == tempID);
try{
(stu);
anges();
= "Delete successfully";
}
catch{
= "Failed To Delete";
}
}
最后再给出一个对实体类实行更新操作的示例:
【例15-5】在解决方案下新建一个网站并添加对DataEntities的引用。参照图15-9设计主页面,在文件中输入以下代码:
图15-9在该界面下更新记录
„
private ntities de = new ntities();
private List
protected void btnUpdateStudent_Click(object sender, EventArgs e)
{
string strStName = ();
bool strStSex = edValue == "男" ? true : false;
string strStScore = ();
if (!OrEmpty(strStName)){
dent student = new dent();
= strStName;
= strStSex;
lScore = 16(strStScore);
UpdateStudentEntity(16(edValue),
student);
= "update successfully";
return;
}
= "Failed to update";
}
private void UpdateStudentEntity(int ID,dent NewStudent)
{
dent oldStudent
= rDefault(c => == ID);
if (oldStudent != null){
try{
= ;
= ;
lScore = lScore;
anges();
}
catch(Exception ex){
//log system error
}
}
}
15.3 Linq基础知识
Linq (Language Integrated Query,语言集成查询), 是.NET Framework 3.0中新增的功能。Visual
Studio 2008及后续版本中在新建项目的模板中都默认添加了using linq,可见微软极其看重该项新增的功能。
15.3.1 Linq及其常用关键字
因为Linq提供了对不同数据源的抽象层,所以查询不同的数据源可以用相同的语法。以下为使用Linq处理数据的主要优点:
1、Linq语法简便易书写,在 VS2008、VS2010、VS2012 IDE下具有非常的智能提示功能。
2、编译器会自动检查表达式语法错误与类型安全性而无需程序员书写额外的代码,可避免类似SQL注
入之类的安全性隐患。
3、Linq提供强大的对数据过滤、排序、分区、分组等处理功能。
4、Linq能直接处理XML数据,对其进行查询等其他处理。
5、Linq支持多数据源和多数据格式的数据。
在C#下可直接使用Linq的关键字构建数据查询语句(表达式)。.NET Framework 3.0之后的编译器中能够对其进行编译。Linq的查询语句有点类似关系数据库的SQL语言的命令,表15-1对 Linq中常用的关键字做简单介绍:
表15-1
Linq查询中常用的关键字
关键字
by
from
group
in
into
join
let
描 述
一般可与group搭配。在group „ by后跟分组依据
查询操作范围变量。from后可跟一个变量
用于对查询结果分组。group后可跟数据源
跟在in关键字后的变量代表数据源。数据源必须是实现IEnumerable
可跟在group子句后面使用,表示将分组结果存放到某变量。该变量默认须有一个Key属性,类型为IGrouping类型
可连接多个数据源进行查询
用于自定义变量并赋予表达式
orderby 表示将查询结果排序(“升序”或“降序”)
select 查询结果的类型和表现形式。与SQL中查询类似,但此处应看作是新建的对象或者对象集合。另外,与SQL不同之处为,Linq中select一般位于查询语句的末尾
var 在方法范围中使用var声明的变量可以具有隐式类型 。 隐式类型的本地变量是强类型的,但其类型由编译器按照实际情况来确定
where 与SQL中的where的作用相似,可起到范围限定也就是过滤的作用
下面给出若干应用linq表达式查询的示例:
【例15-6】在控制台应用程序项目中输入以下代码:
using System;
using tions;
using c;
using ;
class student {
public string StId;
public string ClassId;
public string StName;
public int StTotalScore;
}
class LINQQuery
{
static void Main(){
List
(new student { StId = "20114284",
StName = "John", ClassId = "11302", StTotalScore = 92 });
(new student { StId = "20114286",
StName = " Peter", ClassId = "11302", StTotalScore = 70});
(new student { StId = "20123922",
StName = "Jack", ClassId = "12114", StTotalScore = 85});
//以下定义一个Linq查询语句
var stuQuery =
from stu in students
where d == "11302"
select stu;
//以下为执行该查询并输出其结果
foreach (student stu in stuQuery){
(+ " " );
}
}
}
本例中使用的linq语句用到了from、in、where、select这几个关键字,其中的含义一望便知。与SQL相比一个明显差别是select子句被置于语句末尾。作为数据源的students,在本例中是一个List
执行本例程序的输出为:
John Peter
下面是一个使用Linq进行分组查询的示例:
【例15-7】本例的查询使用与上例中相同的数据源,但需要按照班级分组。可从例15-6复制前半段的代码,然后输入下面位于省略号之后的代码:
…
var stuQuery1 =
from stu in students
group stu by d into g //将学生按classId分组
select new { , num = (),
avgscore = e(st=>lScore)}; //对分组可使用聚合函数
//以下为输出该查询的结果:每个班级的人数及其平均成绩
foreach (var sg in stuQuery1){
ine("ClassId={0} stuCount={1} avgScore={2}",
, , re);
}
本例中使用 group和 by 定义分组方式,into 表示将分组结果存放到的变量,该变量会默认有一个Key属性,即为by 的依据(组别),该变量类型是IGrouping类型, 所以查询返回结果是IGrouping的一个集合。值得注意的是在select之后利用 new新建对象来定义该查询输出对象的形式,在这里可以使用Count 、Average等“聚合函数”。在本例中就是ClassId,st=> 是Lambda表达式,适合在此场合下使用。本质上讲,Linq的分组与SQL的分组也是十分相似的。但Linq下可使用的“聚合函数”远较SQL中更加丰富,还可以用自定义方法。因此,比SQL功能更加强大。
执行本例程序的输出为:
ClassId=11302 stuCount=2 avgScore=81
ClassId=12114 stuCount=1 avgScore=85
与SQL类似,Linq可以用join关联两个集合。下面给出一个示例:
【例15-8】本例在students以外,再另外定义一个集合scoreList,然后在查询中对二者进行关联。请输入以下代码:
„
class scoreRec
{
public string StId;
public string CName;
public int Score;
}
class LINQQuery
{
static void Main()
{
„ //此处可类似例15-6中那样定义students
List
(new scoreRec
{ StId = "20114284", CName = "English", Score = 88 });
(new scoreRec
{ StId = "20114286", CName = "English", Score = 73 });
var stuQuery2 =
from a in students
join b in scoreList
on equals
select new { StId = , StName = , Score = };
foreach (var rec in stuQuery2){
ine("{0},{1}: {2}", rec. stuId, e, );
}
}
}
本例中查询时使用了join关键字连接students和 scoreList两个集合。join 之后的on子句用于指定关联的条件。这也是和SQL中基本是一致的。运行时执行该查询的输出结果为:
John: 88
Peter: 73
15.3.2 Linq to SQL
Linq的查询本质上只是对内存中的一组对象进行的,因此也被称为Linq to Objects。但实际应用中的数据大都来自数据库。为了用Linq处理数据库的数据,需要将数据库的表映射到内存中再处理。有许多方法可以将数据库的数据转换为内存中适合Linq处理的对象,例如15.2节中介绍的实体框架(Entity
Framework)和本节中将要介绍的LINQ to SQL。
LINQ to SQL 是 .NET Framework 3.5 中的一个组件,提供用于将关系数据作为对象管理的运行时基础结构。在 LINQ to SQL 中,关系数据库的数据模型映射到用开发人员所用的编程语言表示的对象模型。 当应用程序运行时,LINQ to SQL 会将对象模型中的语言集成查询转换为 SQL,然后将它们发送到数据库进行执行。当数据库返回结果时,LINQ to SQL 会将它们转换回您可以用您自己的编程语言处理的对象。
Visual Studio 2008提供了一个与对象映射相关的ORM设计器,它允许以可视化方式设计数据要映射的对象。下面通过一个示例简单介绍如何使用 LINQ to SQL组件。
【例15-9】新建一个解决方案,在该方案下新建一个类库,命名为LinqToSQL。在解决方案资源管理器中右击LinqToSQL,从打开的菜单中选择Add New Item,添加一个Linq to SQL 类,如图15-10 所示:
图 15-10 在类库中添加“LINQ to SQL Classes”组件
添加完成后,系统会生成若干文件。然后在IDE下打开服务器资源管理器,并连接上数据库服务器。这里我们仍使用例15-1中曾经使用的SSC数据库,在数据库资源下选中SSC的几个表并以拖曳方式将它们放入到设计器中选项卡的窗口内,如图15-11所示:
图 15-11 将选中的数据表放进的窗口
接下去就可对类库进行编译,然后在解决方案下新建web应用程序项目,并在项目中添加对此类库的引用。假定我们要在页面上显示SSC数据库中的所有学生的信息,为此在中添加一个
GridView控件和一个Label控件,并在该页面的代码文件中输入以下代码:
„
Public partial class Default:
{
Protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack){
LoadDataByLinqToSQL();
}
}
Private void LoadDataByLinqToSQL(){
assDataContext dc = new assDataContext();
urce = ();
nd();
}
}
图15-12为通过浏览器访问该页面时显示的内容:
图15-12通过Linq to SQL类访问学生信息
从代码中可以看出,Linq to SQL组件生成的类可以自动完成对数据库的访问。用户只要调用该类的DataClassDataContext方法创建对象,该对象中就已经包含了所需的数据,可将其作为数据显示控件的DataSource用于显示。不仅如此,上述对象还提供可用于删除、增加和更新数据行的方法。请看以下几个示例:
【例15-10】在例15-9的Web应用程序项目中,新增一个Web窗体。按照图15-13为该页面设计界面,然后在其代码文件中输入以下代码:
图15-13通过Linq to SQL类添加记录
Protected void Button1_Click(object sender, EventArgs e)
{
string strStID = ();
string strStName = ();
bool bolStSex = edValue==
"1" ? true:false;
string strStPhone = ();
string strStTotalScore = ();
assesDataContext dc = new assesDataContext();
dent student =
new dent{
StID = strStID;
StName = strStName;
StPhone = strStPhone;
StSex = bolStSex;
StTotalScore = (strStTotalScore)
};
try{
OnSubmit(student); //插入一条记录(位于内存对象)
Changes(); //将数据变动提交给服务器(用于更新数据库)
("");
LoadDataByLinqToSQL();
}
catch (Exception ex){
throw new Exception(e);
}
}
【例15-11】新增一个Web窗体,在该页面界面上加入GridView,在GridView中添加一列“Delete”命令按钮,如图15-14所示。然后在代码文件中输入以下事件代码:
图15-14通过Linq to SQL类添加记录
Protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int ID = 32([ex].Cells[0].Text);
assesDataContext dc = new assesDataContext();
//以下语句在 tblStudent列表中按 ID查找记录,其中有使用Lambda表达式
dent student = rDefault(c=>==ID);
if(student != null){
try{
OnSubmit(student); //删除内存表中记录
Changes(); //将数据变动提交给服务器(用于更新数据库)
("");
LoadDataByLinqToSQL();
}
catch (Exception ex){
throw new Exception(e);
}
}
}
【例15-12】新增一个Web窗体,该页界面可在基础上做以下修改:在GridView中添加一列“Selete”按钮,并将button控件的Text改为“更新”,如图12-15所示。然后再输入以下事件代码:
图15-15 通过Linq To SQL类更新数据
Protected void GridView1_SelectedIndexChanging(object sender,
GridViewSelectEventArgs e) //对被选的记录复制到编辑区域供修改
{
int ID = 32([ectedIndex].Cells[0].Text);
assesDataContext dc = new assesDataContext();
dent student = rDefault(c=>==ID);
if(student != null){
= ;
= ;
= e;
= lScore;
if((bool) )
edValue== "1";
else
edValue== "0";
}
= ng(); //该文本框的Visible应预设为false
e = true;
}
Protected void Button1_Click(object sender, EventArgs e) //执行“更新”
{
string strUpdatedStID = ();
if(!OrEmpty(strUpdatedStID)){
int StID = 32(strUpdatedStID);
string strStID = ;
string strStName = ();
bool bolStSex = edValue ==
"1" ? true : false;
string strStPhone = ();
string strStTotalScore = ();
assesDataContext dc = new assesDataContext();
dent student= rDefault(c=>==StID);
if(student!=null)
{
try{
= strStID;
= strStName;
= bolStSex;
e = strStPhone;
lScore = strStTotalScore;
Changes();
("");
}
catch (Exception ex){
throw new Exception(e);
}
}
}
}
从以上示例看出,Linq to SQL组件生成的类可以不必使用SQL就实现对相应数据进行增、删、改的基本操作。程序员不必关心数据库操作是怎样完成的。至于数据库查询,可在Linq to SQL的支持下使用Linq,同样不必使用SQL。以上述SSC的数据为例,如果查询全体学生,可以使用以下代码:
assesDataContext dc = new assesDataContext();
var students= ();
var stuQuery =
from stu in students
where == true
select stu;
urce = stuQuery;
nd();
15.3.3 Linq to XML
LINQ to XML 是一种启用了 LINQ 的内存 XML 编程接口,可以用于在 .NET Framework 编程语言中处理 XML。LINQ to XML 将 XML 文档置于内存中,这一点很像文档对象模型 (DOM)。 您可以查询和修改 XML
文档,修改之后,可以将其另存为文件,也可以将其序列化然后通过Internet 发送。
Visual Studio 2008支持LINQ to XML,使用时需要在项目中添加对 和命名空间的引用。
Linq To XML的主要优势在于:
1. 与语言集成查询 (LINQ) 的集成。 因此,可以对内存 XML 文档编写查询,以检索元素和属性的集合。LINQ to XML在功能上(尽管不是在语法上)与 XPath 和 XQuery 具有可比性。
2. 通过将查询结果用作 XElement 和 XAttribute 对象构造函数的参数,实现了一种功能强大的创建 XML 树的方法。
下面提供通过几个示例简单介绍如何使用Linq To XML。
【例15-13】本例通过调用 XDocument和XElement类对象的方法创建XML文档并添加数据。请在控制台应用程序中编写以下代码:
using System;
using tions;
using c;
using ;
using ;
using ;
class TestLinqToXML
{
static void Main(){
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Books")); //创建内存XML对象
XElement root = ; //引用该XML的根节点
//以下语句创建三个XML元素Book,并添加到doc对象中(作为Books的子元素)
( new XElement("Book", new XAttribute("BookID", "0002"),
new XAttribute("BookName", "C#语言程序设计"),
new XAttribute("BookPrice", "50")));
( new XElement("Book", new XAttribute("BookID", "0003"),
new XAttribute("BookName", "数据库系统概论"),
new XAttribute("BookPrice", "40")));
( new XElement("Book", new XAttribute("BookID", "0006"),
new XAttribute("BookName", "软件工程"),
new XAttribute("BookPrice", "35")));
string xmlpath = "C:";
(xmlpath); //将其保存为XML文档
}
}
本例程序运行后,在C盘生成一个名为的XML文件,其中包含如下内容:
BookName= 'C#语言程序设计' BookPrice='50' /> BookName= '数据库系统概论' BookPrice='40' /> BookName= '软件工程' BookPrice='35' /> 对于内存中的XElement对象,可以使用Linq并结合XElement中的方法进行查询。例如: 【例15-14】本例使用例15-13中建立的XML文档的数据,通过XElement类的Load方法创建内存中XML树结构,然后用Linq进行查询。其代码如下: „ class TestLinqToXML { static void Main(){ string xmlpath = "C:"; XElement xe = (xmlpath); //将XML文档加载到内存 string strID = "0003"; var elements = from e in ts("Book") where ute("BookID").Value == strID select e; if (elements!=null){ XElement e1= (); //返回结果集中第一个(也是唯一)元素 ine("BookID={0}, BookName={1}", strID,ute("BookName").Value); } } } 本例程序运行时,控制台输出查询结果为: BookID= 0003, BookName= C#语言程序设计 如果要更新或删除 XML文档的内容,可以先将其加载到内存,然后利用XElement类对象的方法进行处理,最后再将其保存到文件即可。 【例15-15】本例可对上述XML文档中 BookID 为 0006的 Book元素进行修改,使其BookPrice改为29。其代码如下: „ class TestLinqToXML { static void Main(){ string xmlpath = "C:"; XDocument doc = (xmlpath); XElement e1 = ; //e1为XML的根元素(Books) foreach (XElement e in ts()) if (ute("BookID").Value == "0006"){ ributeValue("BookPrice", "29"); //该方法修改元素的属性 break; } (xmlpath); } } 本例中SetAttributeValue 用来修改属性的值。如果要添加或删除属性,XElement类中也有相应的方法可调用。如果要删除 XElement类型的元素本身,则可以使用Remove方法。例如,将if语句下面一行改为 (); 则本例程序执行的结果是将 BookID 为 0006的 Book元素删除。


发布评论