控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

扩展 Entity Farmework 支持随机排序

作者:未知 出处:cnblog 2012年12月24日 阅读:

 在SQL 中,随机排序是如下SQL语句:

 
1 Select * from user order by newid(); 
Linq to object 中随机排序如下:
 
var users = new int[] {1,2,3,4,5};
Users.OrderBy(d=>Guid.NewId()); 
那么在EF中随机排序是怎样写呢? 
 
var query = from a in context.Users
                    order by Guid.NewId()
                    select a;
Var users = query.ToList();
可以负责任的告诉你,以上代码行不通。如果是EF4以前的版本,直接报错。如果是EF以后的版本则会忽略排序。
 
那该怎样才能让EF支持随机排序呢?
 
网上有一篇文章介绍Linq to SQL,http://www.cnblogs.com/Mirricle/archive/2007/08/16/858260.html ,代码如下:
 
 
[Function(Name = "NEWID", IsComposable = true)]
public Guid NEWID()
{
     return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
}
//使用
var customer = (from c in ctx.Customers orderby ctx.NEWID()).First();
 
在实践过程中,发现这样做起来很麻烦。首先需要在每个DBContext中写这样的方法。如果换一个项目又要写一次。
 
有没有简洁的方法呢?
 
从SqlFunctions中找答案吧。SqlFunctions中添加了大部分SQL server中的函数,但遗憾的是没有NewId,我们可以自己写一个。
 
 
/// <summary>
/// Contains function stubs that expose SqlServer methods in Linq to Entities.
/// </summary>
public static class SqlFunctions
{
     /// <summary>
     /// Proxy for the function SqlServer.NEWID 
     /// </summary>
     [EdmFunction("SqlServer", "NEWID")]
     public static Guid NewId()
     {
         throw new NotSupportedException();
     }
}
 
然后为IQueryable<T>添加一个扩展方法:
 
public static IQueryable<T> OrderByRandom<T>(this IQueryable<T> source)
{
     return source.OrderBy(d => SqlClient.SqlFunctions.NewId());
}
最后写个单元测试:
 
 
[TestMethod]
public void OrderByRandomTest()
{
     using (var context = IoC.Resolve<WitnessGodContext>())
     {
          var u1 = context.Users.OrderByRandom().FirstOrDefault();
          var u2 = context.Users.OrderByRandom().FirstOrDefault();
           Assert.AreNotEqual(u1.UserId, u2.UserId);
       }
}
 
通过单元测试。以下是通过QL Profile监视数据库生成的SQL语句:
 
 
SELECT TOP (1) 
....
FROM ( SELECT 
   NEWID() AS [C1], 
   ....
   FROM [dbo].[User] AS [Extent1]
)  AS [Project1]
ORDER BY [Project1].[C1] ASC
 
后记
 
当然这种写法有它的局限性,首先数据库必须是SQL Server,不过目前使用EF,数据库几乎大都是SQL Server。大家可以放心使用,如果要支持多数据库也是有办法的。具体怎么做留待读者自己去摸索吧!

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统