代码改变世界

Linq To Sql 笔记

2011-04-24 09:01  ※森林小居※  阅读(269)  评论(0编辑  收藏  举报

  Linq To SQL 无非是把合法的Linq查询表达式应用于存储在关系数据库中的数据。除查询本身外,Linq To SQL还提供了许多位于System.Data.Linq.dll程序集中的类型,便于代码库与物理数据库引擎间的数据交互。

  Linq To SQL的主要目的是在关系数据库和它们进行的交互编程逻辑间提供一致性。通过使用Linq查询表达式和定义的实体类,及DataContext类型,你可以进行所有预期的数据库的增、删、改、查操作,及定义事务性上下文,创建新的数据库实体或整个数据库、调用存储过程和其他以数据库为中心的活动等。

  此外,Linq To SQL中的类型可与标准的ADO.NET数据类型集成。如,一个重载的DataContext构造器接受一个与IDbConnection兼容的对象作为输入。通过这样的方式,现有的ADO.NET数据访问库可以与C# 3.0 Linq查询表达式集成起来,反之亦然。事实上,就微软而言,Linq To SQL只是ADO.NET大家庭的新成员而已。

实体类的作用

  当你在应用Linq To SQL时,要做的第一步就是定义实体类。简而言这,实体类代表你要交互的关系数据类型。

  当你定义完实体类后,就可以使用DataContext类型把查询表达式传到关系数据库了。该类型负责把你的Linq查询表达式翻译成适当的SQL查询语句,以及和特定的数据库做数据交换等。DataContext类型有许多成员,这些成员把查询表达式的结果映射到你定义的实体类。

  DataContext类型还定义了一个工厂模式,用于获取可在代码库中使用的实体类的实例。在获取一个实体实例后,就可以随便改变它的状态,然后把修改的对象提交给DataContext处理。

  假定我们的数据库中有一个Car表,该表结构如下:

  列名  数据类型
  ID    string  主键
  Name   string
  Speed  string

  我们VS为该表定义一个实体类:

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

namespace LinqTest
{
[Table]
class Car
{
//指明主键
[Column(IsPrimaryKey
=true)]
publicstring ID;
[Column]
publicstring Name;
[Column]
publicint Speed;

publicoverridestring ToString()
{
returnstring.Format("ID = {0}, Name = {1}, Speed = {2}", ID, Name, Speed.ToString());
}
}
}

  注意:定义实体类必须导入命名空间System.Data.Linq.Mapping和System.Data.Linq。

  我们的实体类上添加了Table特性,每个公共字段都标记了Column特性。在这两种情形下,所有的名字都直接映射到了对应物理数据表的名字上。但TableAttribute和ColumnAttribute类型都支持Name属性,这样,我们可以把数据表的编程表示名称与物理的数据表名称本身分离开。还要注意ColumnAttribute类型的IsPrimaryKey属性,该属性表示被修饰字段对应于数据表的主键。

  为简单起见,此处每个字段都声明为公共的。当然,我们也可以定义私有字段,然后用公共属性封装。这种情况下,我们应该用Column特性来标记这些公共属性(而不是字段)。

  实体类可以包含并不映射到数据表中的任意数目的成员。就Linq运行时而论,只有那些标记了Linq To SQL特性的项才会用在数据交换中。

  我们有了实体类,就可以利用DataContext类型来把我们的查询表达式提交给指定的数据库。

  示例代码:

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

namespace LinqTest
{
class Program
{
staticvoid Main(string[] args)
{
//创建一个DataContext对象
DataContext db =new DataContext(@"Data Source=.\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True");

//获取Car表数据到Table<Car>对象
Table<Car> carTable = db.GetTable<Car>();

//显示Car表中所有数据
foreach(var car in carTable)
{
Console.WriteLine(car.ToString());
}

//使用Linq查询Speed>10的记录
foreach (var car in from c in carTable where c.Speed >10 select c)
{
Console.WriteLine(car.ToString());
}

//使用Lambda查询Speed>10的记录
foreach (var car in carTable.Where(car => car.Speed >10))
{
Console.WriteLine(car.ToString());
}

Console.ReadKey();
}
}
}

  虽然上例中就数据库查询而言是强类型的,但在DataContext和它保持的Car实体类间还有点脱节。解决此问题,更好的办法是创建一个扩展DataContext类型的类,在其中为它操作的每个表定义成员变量。

  示例代码:

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

namespace LinqTest
{
class TestDatabase : DataContext
{
public Table<Car> Car;

public TestDatabase(string connStr)
:
base(connStr)
{

}
}
}

  现在我们能把Main方法中的代码极大简化了。

  示例代码:

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

namespace LinqTest
{
class Program
{
staticvoid Main(string[] args)
{
//创建强类型DataContext对象
TestDatabase db =new TestDatabase(@"Data Source=.\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True");

//显示Car表中所有数据
foreach(var car in db.Car)
{
Console.WriteLine(car.ToString());
}

//使用Linq查询Speed>10的记录
foreach (var car in from c in db.Car where c.Speed >10 select c)
{
Console.WriteLine(car.ToString());
}

//使用Lambda查询Speed>10的记录
foreach (var car in db.Car.Where(car => car.Speed >10))
{
Console.WriteLine(car.ToString());
}

Console.ReadKey();
}
}
}

Linq To SQL查询表达式到底是什么?

  Linq To SQL的好处在于,我们能够用统一的、基于对象的模型来与关系数据库交互。那Linq查询表达式到底是什么呢?我们看看下面代码的输出:

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

namespace LinqTest
{
class Program
{
staticvoid Main(string[] args)
{
//创建强类型DataContext对象
TestDatabase db =new TestDatabase(@"Data Source=.\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True");

//定义一个查询结果集
var car = from c in db.Car where c.Speed >10 select c;
//看看这里输出什么?
Console.WriteLine(car.ToString());

Console.ReadKey();
}
}
}

  这段程序输出如下图:

  你也许会惊讶,查询表达式的字符串显示了内部的SQL查询语句,现在您知道Linq To SQL的查询表达式到底是什么了吧。

  Linq To SQL的内容远不止这些,我们使用Visual Studio仅仅拖拽鼠标就能自动创建出Linq To SQL项,而它的功能强大到让人惊叹!所有数据表的增、删、改、查操作均被封装好了,我们只需简单调用就行了。