Issuu on Google+

Entity SQL Language 一 简介

本篇约定 •

文章中只讲 Entity SQL 不讲 EDM 或 Linq to Entities,EDM 的 Context 一 律叫做 db 或 DB

数据库基本以 EFQuerySamples 的 NorthwindEF 为例,下载可到 http://code.msdn.microsoft.com/EFQuerySamples

文章案 T-SQL 的语法规则渐近讲解

如果有相关知识不清楚的,可以留言问我

其实简介讲的东西后面都会仔细再讲,如赶时间可以不必看

什么是 Entity SQL 这一系列的文章介绍的是 Entity SQL 语言。Entity SQL 算是一门存储独立的语 言,有些类似的 SQL 。它可以对 Entity Data Model (EDM) 进行查询。 Entity SQL 类似 SQL 语言,它的存在是为了查询 ADO.NET Entity Framework(EF),以用于支持 Entity Data Model (EDM) 。EDM 表示一组实 体与关系(ER)的集合,映射到指定的数据源(可以是 MsSql 或其它类型的数 据库)。Entity SQL 支持 EDM,使用户能够有效地查询数据。如需果想学习更 多 EDM 或 Ado.net Entity Framework 的知识,可以参见园子上其它朋友写的文 章。

Entity SQL 与 T-SQL Entity SQL 支持 EDM 的直接查询,包括它的继承及关系。它在语法上与 T-SQL 类似,但也算有很多不同。在下面的共同学习中,我们一起一步一步学习他们 的异同。 它支持以下功能


支持与不支持的查询: 1. from 子句

2. in 和 exists

3. union, intersect,

except 来表示并交差集

4. join 表达式

5. 支持 p.Address.City 这种级联查询

6. 不支持*操作

7. group by 时也要 select k from T as t group by (t.x + t.y) as k 这

种方式 8. 无法使用 T-SQL 的函数

它支持 T-SQL 的子查询和表达式,它可以用于任何支持它的数据库,这里给出 一些合法的表达式: 1+2 *3 "abc" row(1 as a, 2 as b) { 1, 3, 5} e1 union all e2 set(e1) 举一个 Entity SQL 与 T-SQL 之 间对比的例子 T-SQL select t.x + t.y from T as t group by t.x + t.y Entity SQL: select k from T as t group by (t.x + t.y) as k


Entity Sql 也支持这种方式 select Tab.a from Tab

Entity SQL 支持的数据类型 1. 那些基本类型,比如 Int32 和 String

2. EDM 的 schema 中定义的那些类型

3. EDM 的 schema 里没定义的 匿名类型

而在它内部也存在一些关键字 NULL、BOOLEAN、INTEGER、DECIMAL、FLOAT、DOUBLE、STRING、DATETIME、TIM E、DATETIMEOFFSET、BINARY、GUID 这些类型几乎都是可以通用于各种数据库的

Entity SQL Language 二 基本执 行方法、操作符、 Select 及 Where 现在就开始正式的对 Entity SQL 的全面学习,我将按 SQL 的学习过程的套路来 对 Entity SQL 进行学习。

Entity SQL 的执行方法


ObjectQuery<返回类型> query = db.CreateQuery<返回类型>(entitySQL 语 句); 这样就执行了所书写的 Entity SQL。并返回一个 ObjectQuery,它有点近似于 IQueryable。

操作符 在任何语言中,操作符都是很重要的概念,Entity SQL 支持如下操作符。

优先级

作用与类型

符号

1

层级

.,()[]

2

! not

3

乘除

* / %

4

加减

+-

5

比较

< > <= >=

6

相等

= != <>

7

and &&

8

or ||

select、where 的基本语法 where 做为查询最简单的语法它的实现方法如下:select value c from cs as c where e 举一个例子,这也是我们见到的第一个真正的 Entity SQL string entitySQL = "SELECT VALUE c FROM Customers AS c WHERE c.City = 'Seattle';"; ObjectQuery<Customer> query = db.CreateQuery<Customer>(entitySQL); 注意这里


1. select value 的 value 不能省去

2. 语句

3. 区分大小写

4. 后面的";"可以不存在。

5. 上篇说到的,如果 Entity SQL 是 select value Customers

FROM Customers WHERE Customers.City = 'Seattle'也是合 法的 语句与执行结果示例:

Top 子句 Top 的使用如下所示 select value top(1) c FROM Customers AS c WHERE c.City = 'Seattle'

Entity SQL Language 三 Where/Exists/In/Like/ 参数及外 键查询


上文写了关于 Where 及 Select 的基本操作,这一篇讲一下 Where 的进阶操作 先说一下查看所生成的 SQL 的方法,.ToTraceString() 例如: string entitySQL = "select value a from orders as a;"; var query = db.CreateQuery<Orders>(entitySQL); Console.WriteLine(query.ToTraceString());

参数 参数可以通过 CreateQuery 的第二个参数传递进去。 DateTime dt = new DateTime(1997, 1, 1); ObjectParameter[] ps = { new ObjectParameter("dt", dt) }; ObjectQuery<Orders> query = db.CreateQuery<Orders>("SELECT VALUE Orders FROM Orders WHERE Orders.OrderDate < @dt;", ps); 这里通过@dt 将参数传了进去,执行结果:

外键关系 Entity SQL 与其它的查询一样,可以通过外键的关系直接取值或判断,如: ObjectQuery<Orders> query = db.CreateQuery<Orders>( "SELECT VALUE o FROM Orders AS o WHERE o.Customers.Country = 'Mexico';");

我们直接用 o.Customers.Country 这是一个一对多的外键关系。


多条件查询 与 T-SQL 相同,只要用相应的逻辑关键字即可。如: string entitySQL = "SELECT VALUE p FROM Products AS p WHERE p.UnitsInStock < p.ReorderLevel and p.UnitsOnOrder = 0;"; ObjectQuery<Products> query = db.CreateQuery<Products>(entitySQL);

Exists 查询 做为 Where 的一个经常用的谓词,Exists 的使用方法如下: string entitySQL = @"SELECT VALUE s FROM Suppliers AS s WHERE EXISTS(SELECT p FROM s.Products AS p WHERE p.UnitsInStock = 0);"; var query = db.CreateQuery<bool>(entitySQL); 运行后生成的 SQL 如下: SELECT [Extent1].[Address] AS [Address], [Extent1].[City] AS [City], [Extent1].[CompanyName] AS [CompanyName], [Extent1].[ContactName] AS [ContactName], [Extent1].[ContactTitle] AS [ContactTitle], [Extent1].[Country] AS [Country], [Extent1].[Fax] AS [Fax], [Extent1].[HomePage] AS [HomePage], [Extent1].[Phone] AS [Phone], [Extent1].[PostalCode] AS [PostalCode], [Extent1].[Region] AS [Region], [Extent1].[SupplierID] AS [SupplierID] FROM [dbo].[Suppliers] AS [Extent1] WHERE EXISTS (SELECT


cast(1 as bit) AS [C1] FROM [dbo].[Products] AS [Extent2] WHERE ([Extent1].[SupplierID] = [Extent2].[SupplierID]) AND ([Extent2].[ UnitsInStock] = 0) )

IN 查询 In 查询当然也是不可少的。使用方法如下: string entitySQL = @"SELECT VALUE c FROM Customers AS c WHERE c.City in {'Seattle','harbin'}"; var query = db.CreateQuery<Orders>(entitySQL);

LIKE 查询 like 做为一个模糊查询的关键字是一定要支持的。 string entitySQL = @"SELECT VALUE c FROM Customers AS c WHERE c.City like '%at%';"; var query = db.CreateQuery<Orders>(entitySQL);

Between、And 查询 string entitySQL =@"SELECT VALUE c FROM Customers AS c WHERE c.ID between 1 and 100"; var query = db.CreateQuery<Orders>(entitySQL);

Entity SQL Language 四 OrderBy/部分查询结果


Entity SQL 就是 Ado.net Entity Framework 的一种查询语言,它简单灵活,不 被语言版本所限制。

Order By 操作 基本的 OrderBy 操作如下: string entitySQL = "SELECT VALUE c FROM Customers AS c ORDER BY c.ContactName"; var query = db.CreateQuery<Customers>(entitySQL); 如果想要倒序排列的话与 SQL 一样,加上 DESC 就可以了 string entitySQL = "SELECT VALUE c FROM Customers AS c ORDER BY c.ContactName desc"; var query = db.CreateQuery<Customers>(entitySQL); 多条排序规则: string entitySQL = "SELECT VALUE c FROM Customers AS c ORDER BY c.CompanyName ASC, c.ContactTitle DESC"; ObjectQuery<Customers> query = db.CreateQuery<Customers>(entitySQL);

返回部分查询结果 如果你要查询的数据仅是一两个字段,按以前所有的写法,将所有的字段都 Select 了,数据库抽了,服务器也抽了。 所以我们经常会只返回一部分结果,在 Linq 中我们可以通过 select new {}一 个新的对象来实现,在 Entity SQL 中我们可以通过以下方法来实现 using System.Data.Common; //....若干行 string entitySQL = "SELECT VALUE row(c.Phone,c.Country) FROM Customers as c"; ObjectQuery<DbDataRecord> query = db.CreateQuery<DbDataRecord>(entitySQL); query.First()["phone"];//使用方法 暂时还没有找到相关文档提出如何像使用正常类一样的使用这种部分查询结果 但是知道了如何去查询多个表的组合


在 EDM 中添加一个新类,不继承,而是添加属性利用组合来添加新类,比如添 加了 A 和 B 两个实体为属性,而这个新建的类又叫 Two 在写 EntitySQL 时 select 命名空间.Two(a,b)...即可

Entity SQL Language 五 GroupBy、位处理函数、字符串处理 函数 GroupBy 对数据进行分组查询可以使用以下语法: string entitySQL = @"SELECT o.OrderDate, Count(o.OrderID) AS Count FROM Orders AS o GROUP BY o.OrderDate"; var query = db.CreateQuery<DbDataRecord>(entitySQL); 直接进行 Group by 操作 而进行分组时也可以使用 Count、Max、Min、Sum、Avg 这几个函数 使用方法与 SQL 没有什么不同,所以这里仅做介绍

函数 函数部分与一般的 SQL 有些不同这里给出一些例子 按位的与、或、异或操作: db.CreateQuery<Int32>(@"BitwiseAnd(1,0)")//与 全 1 才 1 db.CreateQuery<Int32>(@"BitwiseOr(1,0)")//或 有 1 即 1


db.CreateQuery<Int32>(@"BitwiseXor(1,0)")//异或 不同为 1 字符串处理(SampleQueries 这部分的不少例子有错误,请大家见机更正,以下 示例都为正确示例): db.CreateQuery<Int32>("IndexOf('d','zhongdian')")//获取前面字符串在 后面字符串中的位置,本例结果为 6 db.CreateQuery<string>("Right('zhongdian',3)")//右取长度 3 的字符串, ian db.CreateQuery<string>("Left('zhongdian',4)")//左取长度 4 的字符串, zhon db.CreateQuery<string>("Length('abc')")//字符串长度,3 db.CreateQuery<string>("SUBSTRING('zhongdian',2,3)")//子字符串,索 引 2 开始,取长度 3,hon db.CreateQuery<string>("LTrim(' ”

text

')")//去除左边空格,“text

db.CreateQuery<string>("RTrim(' text”

text

')")//去除右边空格,“

db.CreateQuery<string>("Trim(' “text”

text

')")//去除两边空格,

db.CreateQuery<string>("Replace('zhongdian','zhong','chong')")//替 换,将参数 1 中的参数 2 换为参数 3,chongdian db.CreateQuery<string>("ToLower('Abc')")//转小写,abc db.CreateQuery<string>("ToUpper('Abc')")//转大写,ABC db.CreateQuery<string>("Reverse('Abc')")//反转,cbA


Entity SQL Language 六 数字函数、 时间函数及其它 函数 数字函数: db.CreateQuery<double>("Round(1.4)")//四舍五入 db.CreateQuery<double>("Floor(1.9)")//向下取整,即省去小数部分 db.CreateQuery<double>("Ceiling(1.1)")//向上取整,无论小数部分多大 都进 1 时间函数: db.CreateQuery<DateTime>("CurrentDateTime()")//获取当前时间 db.CreateQuery<DateTime>("CurrentUtcDateTime()")//获取格林威治时间 db.CreateQuery<DbDataRecord>("SELECT o.RequiredDate, Year(o.RequiredDate), Month(o.RequiredDate), Day(o.RequiredDate), Hour(o.RequiredDate), Minute(o.RequiredDate), Second(o.RequiredDate) FROM Orders AS o");//获取时间的年,月,日, 时,分,秒的值 GUID 函数: db.CreateQuery<string>("CAST(NewGuid() as System.String)")//生成一 个 GUID 值 用途:可以利用 GUID 来进行随机取数据(即 OrderBy NewGuid()) Entity SQL Language 的入门知识就介绍到这里。


Entity sql framework