快速上手Linq to Sql

本文不是一篇关于Linq to Sql的大百科,写本文的目的,是引导大家快速上手Linq to Sql,所以不可能面面俱到去讲解Linq to Sql。不过根据80-20定律,学会了本文的内容,基本就可以应付80%的工作了。本文将通过案例的方式帮大家上手Linq to Sql。案例是一个“公告发布程序”。下面我们开始!

  Step1:建立数据库
在使用Linq to Sql前,我们要将相应的数据库建好。在这个Demo中,使用的数据库是SQL Server Express 2005。
我们首先建立一个叫的数据库MyBulletin,及两个数据表:Category和Bulletin,分别表示公告的分类和公告,建立方法不再赘述。至于两个表的具体字段请参看图1。

01

图1、数据表结构

其中Category和Bulletin存在一个一对多的关联,表示一个分类下可以有多条公告。

  Step2:建立LINQ to SQL Classes文件
数据建好后,我们需要建立LINQ to SQL Classes文件。这种文件是Linq to Sql框架的主要文件,后面自动生成的实体类和ORM代码都存在于这个文件中。
我们打开VS2008,新建一个C# Class Labrary工程,名称为LinqToSqlDemo.Orm,建好后在工程上单击右键,选择“Add”->“New Item”,在文件类型中选择“LINQ to SQL Classes”,文件名命名为“DataClasses.dbml”,如图2所示。

02

图2、新建LINQ to SQL Classes文件

  Step3:根据数据库表自动生成代码
当建好LINQ to SQL Classes后,VS主界面中自动打开了这个文件。可以看到,这个文件实际是一个设计文件,目前还不包含任何代码和元素。下一步就是利用我们刚才的数据库自动生成ORM代码了。
打开Server Explorer面板。一般它位于VS的左上角,如果没有,请到View菜单中去打开。然后在Date Connections上右键单击,选择“Add Connection”,从这里添加对数据库MyBulletin的连接。

03

图3、添加数据库连接

如图3所示,在Server name中填入SQL Server数据库服务的名字,如果使用的是SQL Server Express 2005,服务名一般是“计算机名\SQLEXPRESS”的格式,然后在“Select or enter a database name”中选择MyBulletin,单击“OK”,就连上我们所需的数据库了。
这时,展开这个连接下的Tables节点,应该能看到Category和Bulletin两个表,选中两个表,将它们拖到DataClasses.dbml的设计区,就会看到如图4所示的样子。

04

图4、设计视图

然后,按Ctrl+S保存,OK!ORM构建完了!
没有骗你,所有需要的代码已经生成完成,现在可以使用它们操作MyBulletin数据库了。不要怀疑,Linq to Sql使用起来就是这么轻松加愉快,不需要写一行代码,也不需要写一个XML字符,ORM就构建完了!
我知道你没看到生成的东西可能不太放心,那么你可以在Solution Explorer里展开DataClasses.dbml节点,看到里面的DataClasses.designer.cs文件没,打开它,里面就是刚才自动生成的代码,我们的数据访问操作就靠这些代码了。另外顺表提一下,数据库的连接字符串放在工程根目录下的app.config文件里,这也是自动生成的,打开它,就可以看到连接字符串。以后如果要修改连接字符串,就修改这里。
好了,ORM构建好了,下面我们看看怎么用。

  Step4:使用Linq to Sql访问数据库
我们首先新建一个工程。为了简单起见,我们就直接建立一个C# Console Application测试我们的ORM吧。将这个工程命名为LinqToSqlDemo.Test。当然,建好工程后,不要忘了添加对工程LinqToSqlDemo.Orm的引用,还要添加对“System.Data.Linq”命名空间的引用。
然后,我们打开Program.cs文件,将其中的内容替换为如下测试代码。

using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Text;

using LinqToSqlDemo.Orm;

namespace LinqToSqlDemo.Test
{
class Program
{
private static DataClassesDataContext dataContext = new DataClassesDataContext();

private static void Output()
{
// 输出分类信息
foreach (Category c in dataContext.Categories)
{
Console.WriteLine(
" 分类 " + c.ID + " " + c.Name);
}

// 输出体育新闻下的公告信息
Category categorySport = dataContext.Categories.Single(c => c.Name == " 体育新闻 " );
foreach (Bulletin b in categorySport.Bulletins)
{
Console.WriteLine(
" 标题: " + b.Title);
Console.WriteLine(
" 内容: " + b.Content);
Console.WriteLine(
" 发布日期: " + b.Date);
Console.WriteLine(
" 所属分类: " + b.Category1.Name);
}
}

private static void TestInsert()
{
// 生成分类实体类
Category category1 = new Category()
{
Name
= " 国际要闻 "
};
Category category2
= new Category()
{
Name
= " 体育新闻 "
};
Category category3
= new Category()
{
Name
= " 财经快报 "
};

// 生成公告实体类
Bulletin bulletin1 = new Bulletin()
{
Content
= " 曼联晋级冠军杯四强 " ,
Date
= DateTime.Now,
Title
= " 曼联晋级冠军杯四强 "
};
Bulletin bulletin2
= new Bulletin()
{
Content
= " 18:00直播亚冠首尔VS山东,敬请期待!!! " ,
Date
= DateTime.Now,
Title
= " 18:00直播亚冠首尔VS山东 "
};

// 将公告加入相应分类
category2.Bulletins.Add(bulletin1);
category2.Bulletins.Add(bulletin2);

// 加入数据库
dataContext.Categories.InsertOnSubmit(category1);
dataContext.Categories.InsertOnSubmit(category2);
dataContext.Categories.InsertOnSubmit(category3);
dataContext.SubmitChanges();
}

private static void TestDelete()
{
dataContext.Categories.DeleteOnSubmit(dataContext.Categories.Single(c
=> c.Name == " 国际要闻 " ));
dataContext.SubmitChanges();
}

private static void TestUpdate()
{
Category categoryFinance
= dataContext.Categories.Single(c => c.Name == " 财经快报 " );
categoryFinance.Name
= " 财经新闻 " ;
dataContext.SubmitChanges();
}

static void Main( string [] args)
{
Console.WriteLine(
" ==============================Linq to SQL 测试============================== " );
Console.WriteLine();

Console.WriteLine(
" ==============================测试Insert============================== " );
Console.WriteLine();
TestInsert();
Output();

Console.WriteLine(
" ==============================测试Delete============================== " );
Console.WriteLine();
TestDelete();
Output();

Console.WriteLine(
" ==============================测试Update============================== " );
Console.WriteLine();
TestUpdate();
Output();

Console.ReadLine();
}
}
}

一下子看不懂上述代码页没有关系,稍候我们会解释一下。现在,我们先来看运行结果:

06

图5、测试程序运行结果

我们先来看看这段测试程序做了什么事。刚开始,数据库是空的,我们首先插入三个分类,并在“体育新闻”下插入两条公告,这是对Insert的测试。接着,我们删除了“国际要闻”分类,这是对Delete的测试。然后,我们将“财经快报”改为“财经新闻”,这是对Update测试。另外,整个过程的输出当然是对Select的测试。这样,数据库基本的操作都测试过了。从输出结果来看,我们的ORM组件运行很顺利,程序输出正确。

  程序分析
经过简单的四步,我们就完成了通过Linq to Sql操作数据库的过程。下面我们对测试代码进行一个简要的分析,帮助朋友们学会Linq to Sql操作数据库的基本方法。

取得数据库Gateway
要操作数据库,我们首先要获得一个DataContext对象,这个对象相当于一个数据库的Gateway,所有的操作都是通过它进行的。这个对象的名字是“LINQ to SQL Classes文件名+‘DataContext’”,这里,就是DataClassesDataContext了。它和普通对象一样,直接实例化就行了。在Demo里我将它实例化为一个静态变量。
取得DataContext对象后,每个数据表就会映射到其一个集合属性,例如Category表映射到dataContext.Categories,这是一个集合属性,每一个元素是一个实体类,代表此表中的一条记录。实体类名和表名相同。实体类的字段自然就映射到对应表的字段。
还有一点需要注意,数据库中的一对多关系,在Linq to Sql生成代码时会自动表示到类结构中。并且,这种关联是双向的。例如,Category与Bulletin的一对多关系,到了类结构中,反映成如下形式:在Category类中,有一个名为Bulletins的集合属性,内容是所有属于此Category的Bulletin对象的引用。而在Bulletin类中,也会有个Category1属性(由于Category这个名字被我们用了,所以,这个关联属性自动加了个“1”),其内容是此Bulletin所属Category对象的引用。

Insert操作
Insert用于向数据库添加记录。一般情况下,使用“DataContext.表映射集合.InsertOnSubmit(实体类)”的方式就可以完成Insert操作。不过这里要注意一点,由于Linq to Sql使用了“Unit of Work”模式,所以,对数据库的操作不会立即提交到数据库,而要调用DataContext的SubmitChanges方法,所有改动才会被提交到数据库。

Delete操作
Delete操作用于从数据库中删除记录。表映射集合的DeleteOnSubmit方法可以实现这个操作。这个方法需要一个参数,就是要删除的实体类,这里不能直接传个ID去删除,要首先通过ID找到相应实体类,传给DeleteOnSubmit再删除。当然最后不要忘了SubmitChanges。

Update操作
Update操作用于更新数据库中某已存在记录的信息。在Linq to Sql中,Update操作就是首先加载相应的实体类,修改其相应字段后,SubmitChanges就可以了。

Select操作
Select操作用于从数据库中返回指定的记录。在Linq to Sql中,查询结果都是以实体类或实体类集合的方式返回的。其中实体类集合并不是List,如果想转为List,只需在返回结果上调用ToList方法即可。
如果是查询单一记录,建议使用表映射集合的Single方法。至于查询参数,建议采用lambda表达式。如果你对lambda表达式不熟,可以参考这里http://msdn.microsoft.com/zh-cn/library/bb397687.aspx

  其它相关示例代码

常用Select操作举例
取得单个记录(ID为3的分类)

return dataContext.Categories.Single(c => c.ID == 3 ;

取得全部记录(全部分类)

return dataContext.Categories;

得部分记录(所属分类ID为3的公告,按ID降序排列)

return from b in dataContext.Bulletins
where b.Category == 3
orderby b.ID descending
select b;

取得部分记录并分页,最后转换为List(所属分类ID为3的公告并分页,pageSize为每页多少条记录,pageNo为第几页)

var bulletins = from bin dataContext.Bulletins
where b.Category==3
orderby b.ID descending
select b;
return bulletins.Skip(pageSize* (pageNumber-1)).Take(pageSize).ToList();

  总结

好了,这篇文章就到这里了。希望能帮助大家快速上手Linq to Sql。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值