LinqToSql库是一个强大的工具,它能够将LINQ表达式树转换为SQL语句,这些语句可以执行在多种关系数据库管理系统(RDMS)上,而不仅仅是微软的SQL Server。本文将介绍LinqToSql库的主要功能,并展示如何在SQLite、SQL Server和Microsoft Access数据库中使用它进行查询。
LinqToSql库实现了以下功能和特性:
SQLite是一个软件库,它实现了一个自包含的、无服务器的、零配置的、事务性的SQL数据库引擎。SQLite是世界上部署最广泛的SQL数据库引擎。它被用于无数的桌面计算机应用程序以及消费电子设备,包括手机、PDA和MP3播放器。SQLite的源代码是公共领域的。
在下载并安装了SQLite.NET(一个优秀的ADO.NET包装器)和SQLite数据库浏览器(提供SQLite的图形用户界面)之后,将准备好运行下载中的示例。示例中已经完成了以下工作:
将介绍几个设置运算符的例子,包括ALL、ANY和UNION。
以下查询将提供所有已下订单且所有订单都已发货到客户所在城市的客户的列表。
from c in customers
where (
from o in c.Orders
select o
).All(o => o.ShipCity == c.City)
select new { c.CustomerID, c.ContactName };
这将产生以下SQL语句:
SELECT t0.CustomerID, t0.ContactName
FROM Customers AS t0
WHERE (
SELECT COUNT(*)
FROM Orders AS t1
WHERE ((t1.CustomerID = t0.CustomerID) AND NOT ((t1.ShipCity = t0.City)))
) = 0
以下查询将提供所有未下订单的客户的列表。
from customer in customers
where !customer.Orders.Any()
select new { customer.CustomerID, customer.ContactName };
这将产生以下SQL语句:
SELECT t0.CustomerID, t0.ContactName
FROM Customers AS t0
WHERE NOT (
(
SELECT COUNT(*)
FROM Orders AS t1
WHERE (t1.CustomerID = t0.CustomerID)
) > 0
)
以下查询将提供居住在伦敦的客户和员工的列表。
from c in customers.Where(d => d.City == "London")
select new { ContactName = c.ContactName }
.Union(
from e in employees.Where(f => f.City == "London")
select new { ContactName = e.LastName }
);
这将产生以下SQL语句:
SELECT t2.ContactName
FROM Customers AS t2
WHERE (t2.City = @p0)
UNION
SELECT t2.LastName
FROM Employees AS t2
WHERE (t2.City = @p1)
虽然RDMS通过SQL暴露的核心功能在不同数据库之间非常相似,但更高级的功能通常根据使用的产品以非常不同的方式访问。例如,以下查询...
from order in orders
where order.OrderDate.Value.Year > DateTime.Parse("1/1/1997").Year &&
order.CustomerID.StartsWith("B")
select new {
order.CustomerID,
order.OrderID,
order.OrderDate
};
对于SQL Server,翻译将是:
SELECT t0.CustomerID, t0.OrderID, t0.OrderDate
FROM Orders AS t0
WHERE ((datePart(yyyy, t0.OrderDate) > @p1) AND t0.CustomerID Like (@p0 + '%'))
但在SQLite中,翻译将是:
SELECT t0.CustomerID, t0.OrderID, t0.OrderDate
FROM Orders AS t0
WHERE ((round(strftime('%Y', t0.OrderDate)) > @p1) AND Like(@p0 || '%', t0.CustomerID))
LinqToSql库通过不同的数据库系统暴露出核心功能,并且可以通过扩展它来产生针对选择的RDMS的正确SQL语法。下一篇文章将介绍如何扩展LinqToSql以适应不同的数据库系统,以及如何将用户定义的标量函数映射到存储过程/临时SQL。