代码改变世界

年度开源力作,博客园首发,回馈广大用户。【Entity SQL for Linq to SQL】

2012-12-03 14:52  麦舒  阅读(12164)  评论(90编辑  收藏  举报

好久没有在博客园里抛头露面,距离上一篇博客,想来也有一年了吧。这一年,虽然没有写博客,但是还是一直在关注博客园的。这一年当里,博客园似乎变得更为热闹了,但是,发布作品的似乎比之前少了很多,能够一直坚持下来的更是少。很多用户都问到我,ALinq 很什么时候发布新版,还是已经停止更新了。不止一次说过,只要有一个用户在用我的产品,都会更新、维护下去的。因为为什么?梦想!我要开发出世界一流的软件产品,体现自己的价值。

这个开源项目,现在暂且称之为 ALinq Dynamic 吧,原来是准备作为 ALinq3 的一部份的,但是由于现在已经不再全职投入 ALinq 的开发了,担心有些 BUG 无法及时给用户解决,所以决定把它作为一个独立的开源目,发布给各位用户使用。现在这个项目已经放到了 CodePlex 上了,网址是:http://esql.codeplex.com/

现在给大家简单介绍一下这个项目吧。

项目简介:

ALinq Dynamic 是一个将 Entity SQL 语句转换为 Linq Expression 的框架,它不但适用于 ALinq,同样也可以应用于Linq to SQL。

功能特点:

1、支持 Entity SQL 的语法查询。已经实现了Entity Framework 中 Entity SQL 的绝大部份功能。为什么不自创一种语法?因为我希望能尽可能减少用户的学习成本。

2、与 Linq 表达式无缝对接,动态查询,有一个很大的缺点,就是查询结果是弱类型的。但是,在 ALinq Dynamic 里通过索引器查询成功解决了这个问题。

为了让大家对它有个直观的认识,给出一个典型的例子。

var esql = @"select o.OrderId, o.EmployeeId, d.ProductId, p.UnitPrice 
             from Orders as o 
                  Inner Join OrderDetails as d on o.OrderId == d.OrderId
                  Inner Join Products as p on d.ProductId == p.ProductId";


var q2 = db.CreateQuery<IDataRecord>(esql);
var q3 = q2.Select(o => new { OrderId = (int)o["OrderID"], 
                              EmployeeId = (int)o["EmployeeID"], 
                              ProductId = (int)o["ProductId"] })
           .Where(o => o.OrderId > 1000)
           .Join(db.Employees, o => o.EmployeeId, e => e.EmployeeID,
                          (a, b) => new { a.EmployeeId, 
                                          a.OrderId, 
                                          a.ProductId,
                                          b.City, 
                                          b.Address })
           .Take(10);


q3.Execute();

--------------------------------------------------------------------------------------------------------------------------

2012-12-4 更新

由于很多人吐槽上面例子中的 Select,我还是把它稍作改动吧。下面的例子和上面是等价的。

var esql = @"select o.OrderId, o.EmployeeId, d.ProductId, p.UnitPrice 
    from Orders as o 
        Inner Join OrderDetails as d on o.OrderId == d.OrderId
        Inner Join Products as p on d.ProductId == p.ProductId";


var q2 = db.CreateQuery<IDataRecord>(esql);
var q3 = q2.Where(o => (int)o["OrderId"] > 1000)
            .Join(db.Employees, o => (int)o["EmployeeId"], e => e.EmployeeID,
                            (a, b) => new
                            {
                                EmployeeId = (int)a["EmployeeId"],
                                OrderId = (int)a["OrderId"],
                                ProductId = (int)a["ProductId"],
                                b.City,
                                b.Address
                            })
            .Take(10);


q3.Execute();

根据网友的疑问,我再补充一下吧:

1、关于 SQL ,上面的并不是 SQL ,而是 Entity SQL,不知道什么是 Entity SQL 的,Google 一下吧。

2、为什么不直接用 SQL?这个样的问题,实在让我很无语呀,你想想,为什么 EF 要提供一个 Entity SQL,Hibernate 要提供一个 HQL 。实在想不出来,Google 一下为什么要用 ORM,而不用 SQL 吧。

3、在这个示例里,为什么用索引器,而不用 Dynamic ?因为 Linq to SQL 不支持使用 Dynamic 查询,还有,.NET 3.5 也不支持 Dynamice 关键字。

4、ALinq Dynamic ,也就是这个项目,不是一个 ORM 来的,它只是为 Linq to SQL 和 ALinq 提供一个 Entity SQL 的查询接口。它的原理是将 Entity SQL 转换成 Linq Expression 来执行。

5、为什么要给 ALinq,Linq to SQL 提供 Entity SQL 的查询接口?为了更为方便的动态查询。

另外,希望各位朋友,在语气上,稍微谦虚礼貌点。

-----------------------------------------------------------------------------------------------------------------------------

 

 

谁会需要它?

需要用到动态查询的用户。我想,绝大部份用户都会碰到动态查询这个问题,但是,现有的解决方案,都不够好。ALinq Dynamic 的出现,将 会为 ALinq 和 Linq to SQL 用户,提供一个更为好用的解决方案。

如何使用:

1、到 CodePlex 上下载压缩包,网址:http://esql.codeplex.com/ ,然后解压缩。

2、如果你是 ALinq 用户,打开 DynamicQuery.sln 或者 DynamicQuery_VS08.sln 解决方案,其中前者是适用于 VS 2010,后者适用于 VS 2008,

3、如果你是 Linq to SQL 用户,打开 DynamicQuery.LinqToSql.sln (仅适用于 VS 2010 ) 。

4、打开测试项目,然后修改 App.Config,该文件在 DynamicQueryTest 目录下,所用的数据库为 SQLite 和 SQL Compact。

5、查看,并运行单元测试中的范例。

关于文档: 文档和教程,随后将至,请大家留意我的博客。

技术支持: 1、在我的博客留言,我会尽可能地抽时间来答复大家的问题。 2、加入 ALinq 用户的 QQ群(71418067)。

谢谢大家的阅读,麻烦大伙点一下推荐,再次谢谢大家。 ^_^