本系列教程将全面介绍 oql.net ,包括 select、insert、update 和 delete 语句,也包括 select、from、join、on、where、group by、having、order by 和 case 子句。
本系列教程将以 Microsoft SQL Server 的 Northwind 数据库为基础并采用 C# 来写示例代码,有关在 VB.NET 等其他语言中使用的注意事项将在相应的地方进行说明。
1、Select单表的全部字段
Select 语句是我们最为常用的 SQL 语句,也是 DML 中最复杂的语句,就让我们从最简单的 select 语句开始吧:
-- SQL 1 SELECT [Orders].* FROM [Orders] WHERE [Orders].[EmployeeID] = 5 AND [Orders].[ShipVia] = 1 |
上述 sql 语句直接翻译为 oql 是这样的:
// OQL 1 SelectQuery query = OQL .Select(NW.Order) .From(NW.Order) .Where(NW.Order.EmployeeID == 5 && NW.Order.ShipVia == 1); |
从这种简单的翻译我们不难看出,在 oql.net 中,oql 的书写形式和 sql 惊人的相似。
代码中的NW 表示 Northwind 数据库的架构名称,这个名称用来区分于其他的架构。oql.net 允许您在一个程序中同时使用多个数据库架构,这些架构既可以是不同的数据库,也可以是同一个数据库的多个子架构。我们建议将一个较大的数据库按照业务模型划分为多个子架构,这些子架构既可以重叠,也可以完全不同。
因为 SQL 1 是查询一个表的全部字段,属于最简单的 SQL 了,OQL 1 可以简化如下:
// OQL 1-2 SelectQuery query = OQL .SelectWhere(NW.Order.EmployeeID == 5 && NW.Order.ShipVia == 1); |
2、Select单表的部分字段
很多时候我们只需要 select 表中的某几个字段,比如下面的 sql:
-- SQL 2 SELECT [Orders].[OrderID] , [Orders].[OrderDate] , [Orders].[RequiredDate] FROM [Orders] WHERE [Orders].[EmployeeID] = 5 AND [Orders].[ShipVia] = 1 |
翻译为 oql 如下:
// OQL 2 SelectQuery query = OQL .Select(NW.Order.OrderID, NW.Order.OrderDate, NW.Order.RequiredDate) .From(NW.Order) .Where(NW.Order.EmployeeID == 5 && NW.Order.ShipVia == 1); |
Oql.net 的级联表达式是很灵活的,下面的 OQL 等同于 OQL 2。方法“_”也可以用“Add”,特别是在 VB.NET 中由于单个下划线不能作为标识符只能使用 Add 方法。
// OQL 2-2 SelectQuery query = OQL .Select(NW.Order.OrderID)._(NW.Order.OrderDate)._(NW.Order.RequiredDate) //.Select(NW.Order.OrderID,NW.Order.OrderDate).Add(NW.Order.RequiredDate) .From(NW.Order) .Where(NW.Order.EmployeeID == 5 && NW.Order.ShipVia == 1); |
3、动态构造 select 子句
下面的 oql 等效于 OQL 2,所不同的是 OQL 2-3 的 select 子句是动态构造出来的,请注意在 VB.NET 中方法“_”用“Add”代替。
// OQL 2-3 ScalarList selectList = new ScalarList(); selectList.Add(NW.Order.OrderDate); selectList.Add(NW.Order.RequiredDate); SelectQuery query = OQL .Select(NW.Order.OrderID)._(selectList) .From(NW.Order); .Where(NW.Order.EmployeeID == 5 && NW.Order.ShipVia == 1); |
其他子句的动态构造,将在相应的部分作介绍。
4、使用子查询
下面是一个使用子查询的 sql 语句:
-- SQL 3 SELECT [Orders].* FROM [Orders] WHERE [Orders].[CustomerID] IN ( SELECT [Customers].[CustomerID] FROM [Customers] WHERE [Customers].[ContactTitle] = 'Owner' ) |
直接翻译为 oql 如下,形式依然和 sql 极其相似:
// OQL 3 SelectQuery query = OQL .SelectFrom(NW.Order) .Where( NW.Order.CustomerID.In(OQL .Select(NW.Customer.CustomerID) .From(NW.Customer) .Where(NW.Customer.ContactTitle == "Owner") ) ); |
当 oql 语句较长时把子查询抽出来更有利于维护和重用,这有点像重构。下面的 OQL 3-2 等效于 OQL 3:
// OQL 3-2 SelectQuery sub = OQL .Select(NW.Customer.CustomerID) .From(NW.Customer) .Where(NW.Customer.ContactTitle == "Owner"); SelectQuery query = OQL .SelectWhere(NW.Order.CustomerID.In( sub )); |
当表间的约束条件作为子查询的条件时,可以使用对象表达式简化 oql 语句。本例的 Orders 表和 Customers 表是父子关系,通过 CustomerID 进行关联,简化后的 oql 如下:
// OQL 3-3 SelectQuery query = OQL .SelectWhere(NW.Order == (NW.Customer.ContactTitle == "Owner")); |
对象表达式使得 oql 语句变得更简洁,但同时也降低了可读性。
有关 where 子句及多表查询将在随后陆续介绍。