兴国安邦

C# 3.0, Linq, Linq To Sql

博客园 首页 新随笔 联系 订阅 管理
  33 Posts :: 0 Stories :: 553 Comments :: 150 Trackbacks
本节讲orderby操作.我突然在想这么一个问题,读者会T-SQL吗?要是不知道,那我写的是不是太简单了呢?做个调查哦,不知道的举手.
OrderBy操作
简单的,按雇用日期排序,默认为升序
            var q =
                from e 
in db.Employees
                orderby e.HireDate
                select e;
带where条件的,shipcity为london的。
            var q =
                from o 
in db.Orders
                where o.ShipCity 
== "London"
                orderby o.Freight
                select o;

            var q 
=
                from o 
in db.Orders
                orderby o.Freight
                where o.ShipCity 
== "London"
                select o;
在这里where和orderby的顺序并不重要。而在T-SQL中,where和orderby有严格的位置限制。
OrderByDescending的,按价格降序。
            var q =
                from p 
in db.Products
                orderby p.UnitPrice descending
                select p;
ThenBy的和ThenByDescending,也就是按多个列进行排序,第一个列子是先按city,city相同的再按contactname排序,第二个例子中,第二序列为降序。
ThenBy:
            var q 
=
                from c 
in db.Customers
                orderby c.City, c.ContactName
                select c;

ThenByDescending:
            var q 
=
                from o 
in db.Orders
                where o.EmployeeID 
== 1
                orderby o.ShipCountry, o.Freight descending
                select o;
对这两个句子解释下。
对于ThenBy操作,其级连形式为:
       var q 
= db.Customers.OrderBy(c => c.City).ThenBy(c => c.ContactName).ToList();
因为T
-SQL中,并没有ThenBy语句,其依然翻译为OrderBy
所以,也可以用下面语句来表达
var q 
= db.Customers.OrderBy(c => c.ContactName).OrderBy(c => c.City).ToList();
所要注意的是,是两个orderby的顺序,多个orderby操作时,级连方式是按逆序.即先按city排时,city要放在最后。
对于降序的,用相应的降序操作符替换即刻。
        var q = db.Customers.OrderByDescending(c => c.City).ThenByDescending(c => c.ContactName).ToList();

需要说明的是,orderby操作,不支持按type排序,也不支持匿名类。
比如  var q = db.Customers.OrderBy(c => c).ToList();和
var q = db.Customers.OrderBy(c => new {c.City,c.ContactName}).ToList();

会被抛出异常。但是,既然提了,大家在这个问题就不会犯错误,常见的错误是前面的操作有匿名类,再跟orderby时,比较的是类别。比如

var q = db.Customers.Select(c => new { c.City, c.Address }).OrderBy(c => c).ToList();

如果你想使用OrderBy(c => c),其前提条件是,前面步骤中,所产生的对象的类别必须为C#语言的基本类型。比如
var q = db.Customers.Select(c=>c.City).OrderBy(c => c).ToList();
city为string类型。

还有一点需要说明的时,linq和dlinq在orderby操作中,稍微有一点区别。linq支持按type排序,但是,需要你自己去实现IComparable接口。

比如语句:var q = db.Customers.ToList().OrderBy(c => c).ToList();
第一个ToList()会把数据库中所有数据取出,放到内存中,以后所有的操作全部是对内存操作。后面的所有操作均为linq操作,不是dlinq。(这一点,我前面的文章中讲过)如果,你想用按客户进行排序,你必须在Customer类中,实现IComparable接口
其Customer类,必须从IComparable继承,代码如下,
  public partial class Customers : System.Data.Linq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged,IComparable
Icomparable接口的具体实现如下:

        #region IComparable Members

        
public int CompareTo(object obj)
        {
            
return this._CustomerID.CompareTo(((Customers)obj).CustomerID);
            
//throw new Exception("The method or operation is not implemented.");
        }

        
#endregion

Orderby操作,会自动调用该接口的方法,实现按类别排序。如果,你的映射文件中没有实现该接口,系统会抛出异常。
你也可以使用generic,如下,
    public partial class Customers : System.Data.Linq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged,IComparable<Customers>

        #region IComparable<Customers> Members

        
public int CompareTo(Customers other)
        {
            
return this.CustomerID.CompareTo(other.CustomerID);
            
//throw new Exception("The method or operation is not implemented.");
        }

        
#endregion

好处就是你无须把object强制转化为customer类。
我们再来定义个,先按订单号排序,相同订单按产品号排序的。
    public partial class OrderDetails : System.Data.Linq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged,IComparable<OrderDetails>

        #region IComparable<OrderDetails> Members

        
public int CompareTo(OrderDetails other)
        {
            
int k = this._OrderID - other.OrderID;
            
if (k == 0)
            {
                k 
= this._ProductID - other.ProductID;
            }
            
return k;
            
//throw new Exception("The method or operation is not implemented.");
        }

好了,更多的功能,等待大家自己去实现。下次讲Groupby操作。



posted on 2007-01-29 10:59 Tom Song 阅读(7848) 评论(26)  编辑 收藏 网摘 所属分类: C# 3.0

Feedback

zhichi
  回复  引用    

#2楼 2007-01-29 13:25 装配脑袋      
orderby p.UnitPrice descending 貌似比真的SQL关键字还长……
LZ能不能分析一下OrderBy算符的内部实现机制?貌似DLinq上是直接转化成SQL语句,还好说。如果是普通Linq,那么基于IEnumerable<>这种单向前进的读取方式,排序效果就很难说了。它会不会生成一个中间表来储存排序结果呢?

  回复  引用  查看    

真难受!
  回复  引用    

#4楼 2007-01-29 15:24 宋国安
为什么难受?技术更新太快?还是我写的不好?有意见呢要大胆的提哦,我自己才能不断的努力,满足不同人的需求。
@革命老前辈

  回复  引用    

#5楼 2007-01-29 15:28 宋国安
DLinq就是直接转化成SQL语句,由sql来负责排序,然后返回给dlinq。对于linq排序这个吗,我就不是很清楚了。内部算法实现,我们不可能知道的。排序算法多的很。你到是可以研究下。如果,你能从时间上计算出内部是按什么算法排序的,别忘了告诉我们大家呀。
@装配脑袋

  回复  引用    

#6楼 2007-01-29 15:33 装配脑袋      
我没装这个版本阿……
实在太大了

  回复  引用  查看    

#7楼 2007-01-29 15:50 宋国安
装个Linq Preview好了,就可以在VS2005中玩了。
@装配脑袋

  回复  引用    

@宋国安


不是技术更新快,这个东西没什么,说白了就是一SQL转译器,用起来难受而已。对于精通SQL的人来说就是一垃圾。

  回复  引用    

#9楼 2007-01-29 16:54 装配脑袋      
精通SQL的人有两种,一种是把SQL当作纯编程语言来看待的。他们就会发现SQL描述的方式与命令式编程语言的不同,于是就会尝试在C# 3.0中使用新的思想来表达。
还有一种是把SQL当作数据库查询工具,与编程语言完全是天上地下的人。他们认为编程的时候命令式语言为王道。SQL这种只与数据库有关系的东西是不可能融入进来的,硬塞进来也是不伦不类。所以他们就不会使用C#3.0中新语法。

  回复  引用  查看    

#10楼 2007-01-30 08:38 a11s.net      
只有这些吗?

筛选灵活了.这样就把数据库内容全部都一次加载进来?
充分利用空间换取时间?
(过去我曾大力支持将数据库全部加载到内存来换取时间.)

这样数据库的意义又是什么?是不是MS这么想的.反正SQLString我要解析.干脆用这种办法运行的时候就直接编译算了..

我想不出来还能用在什么地方.

真要是用在记录操作.那么这个一定少不了中间层了.foreach record in q 这个record必须自己 update.要是用这个全局的内存DB,多用户的时候会有很多问题.总不能这些冲突都自己解决吧.总感觉以后一定会有好事者做这方面的东西.

能用在什么地方才能使它变得不是很鸡肋?解释明白了这个,学习起来可以一边学一边思考如何应用到实际,我认为这样比较好.单纯讲语法越来越迷茫.

  回复  引用  查看    

#11楼[楼主] 2007-01-30 09:52 宋国安      
我不同意你这个观点。dlinq的出现,大大降低了数据库应用程序开发的门楷,它实质是事先为你构架了数据访问层,势必将加快数据库应用程序的开发进度。dlinq解放了众多程序员,让他们的把更多的精力放到业务逻辑以及code上,而不是数据库。
对于初学者来讲,dlinq可以让他们迅速进入数据库应用程序开发领域,节约了培训成本。(以前,需要懂c#语言,数据库,T-SQL, 还要懂ado.net),现在,只要知道dlinq就可以啦。
@革命老前辈

  回复  引用  查看    

#12楼[楼主] 2007-01-30 09:57 宋国安      
@a11s.net
时间和空间都很珍贵。dlinq的排序是sql server完成的,linq的排序是在内存中完整的。
关于dlinq的应用,凡是能使用ado.net开发的程序,都可以使用dlinq。
还有,你对dlinq理解错误,它并不是一次性把所有数据加载进来。关于这点,请参考前面几个文章。
边学边用到是个很好的建议。我尽量吧。谢谢你。

  回复  引用  查看    

#13楼 2007-02-03 22:03 Woody[未注册用户]
OrderBy in LINQ
http://www.agilelabs.cn/blogs/woody/archive/2007/02/02/1895.aspx

  回复  引用    

#14楼 2007-02-06 00:06 才鸟[未注册用户]
呵呵,你的文章写的很好。但你说“(以前,需要懂c#语言,数据库,T-SQL, 还要懂ado.net),现在,只要知道dlinq就可以啦”,这点我不是太同意。不知道你注意到了没有,在微软推出linq/dlinq的同时,还有ado.net vnext,好像是这样叫的,不知道你对这两者的关系有研究吗?
  回复  引用    

#15楼 2007-02-06 00:10 才鸟[未注册用户]
还有能不能在讲Groupby的操作的时候,讲解一下自定义聚合函数的使用(dlinq内置的聚合函数太少,如标准的stdev和variance都没有),谢谢!!
  回复  引用    

@才鸟:
ado.net vNext现在改名叫:Ado.net Orcas了...一切向Orcas靠拢,呵:)
http://www.agilelabs.cn/blogs/woody/archive/2006/11/22/1744.aspx

  回复  引用    

写的不错,继续努力:)
  回复  引用    

#18楼[楼主] 2007-04-12 09:24 宋国安      
@才鸟
很抱歉,现在才回复你。
贴一个老外的东西给你吧.原文出处

http://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspx">http://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspx

你也可以到这里听听开发人员是怎么说的。
http://channel9.msdn.com/Showpost.aspx?postid=202138">http://channel9.msdn.com/Showpost.aspx?postid=202138

Wednesday, June 21, 2006 10:53 AM by Somasegar
LINQ and ADO.NET innovations
Language-Integrated Query (LINQ) is a breakthrough technology that eliminates the impedance mismatch among different data domains. With LINQ, developers do not need to learn separate query syntaxes when querying over diverse data domains such as XML, Relational and Objects. LINQ has been very well received both last year at its announcement at the PDC, and more recently at Tech-Ed in Boston. Orcas, the next version of Visual Studio, includes LINQ infrastructure that enables this powerful combination of languages and API’s, as well as concrete support in multiple programming languages and data domains.



At the same time, our ADO team has been building a new data mapping substrate called ADO.NET Entities. Entities move the data model up from the physical structure of relational tables to a data model that more accurately represents business entities such as “Customer” or “Order” that could map to multiple relational tables and views. You can think about entities as a declarative way to specify the structure of a business object which you can then add business logic to and, through the power of LINQ, be able to query over them as well. Entities will allow us to provide a common data model within the familiar ADO.NET environment that can be used across high-level functions such as reporting, replication, and BI. For major enterprise applications, Entities allow developers to define complex mapping to relational data, enabling the creation of new business structures when the underlying database schema cannot be changed.



These two major advances in programmatically accessing data will help developers on our platform be even more productive. Check out the channel 9 session that Anders Hejlsberg and Sam Druker did recently on this.



So that you can better identify these technologies, we have simplified our naming scheme as follows:



LINQ to ADO.NET, which includes:

LINQ to DataSet

LINQ to Entities

LINQ to SQL (formerly DLinq)



LINQ support for other data types include:

LINQ to XML (formerly XLinq)

LINQ to Objects



Our teams are busy working on the next version of Visual Studio and incorporating these technologies in a consolidated way to ensure the very best experience for our developers. We have the May CTP for LINQ available here and keep an eye out for a preview of the Entities work before the end of this year.




  回复  引用  查看    

#19楼[楼主] 2007-04-12 09:25 宋国安      
@才鸟
我在努力。:) 工作太忙了,还顾不上这里。

  回复  引用  查看    

#20楼 2007-04-20 17:25 Xiangyu[未注册用户]
比如现在我有两张表,是主子表Header和Detail,
我要在一个Transaction中更新Header的一笔记录和Detail的多笔记录,
通过Dlinq应该如何实现?谢谢

  回复  引用    

#21楼 2007-05-20 09:49 DaiWei[未注册用户]
比如现在我有两张表,是主子表Header和Detail,
我不想使用DataContext的更新方式,我想用自己的方式:
手动控制提交。让我自己控制保存Header,然后我自己篇历Detail,手动去保存每一个,如何用DLINQ实现?

  回复  引用    

#22楼 2008-12-17 15:58 对账[未注册用户]
老大
看了你写的linq入门,收益不少
这两天我一直在想一个问题
之前我们在程序里用sql的时候,是把他穿成字符串然后传递给sql数据库的
但是现在linq不是这样了
以前调试的时候可以吧sql语句print出来,在查询分析器里面验证一下
但是现在linq如何调试??
也不能把他print出来看把

  回复  引用    

很有意思的。。。

我直接来学这个了,

问一个问题

提取出来的var类型数据集合

能不能装换成DataTable类型?

  回复  引用    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 632486




相关文章:

相关链接: