Fork me on GitHub

Linq 随机排序的几种方案。

    今天为了用linq实现 select top 1 * from _table order by newid() 这样一个sql下的常用的方法,折腾了大半天!

 

网上提供了几种解决办法,最经典的是:

1
2
3
4
5
6
7
8
9
1//在自动生成的mapping code中添加
2[Function(Name = "NEWID", IsComposable = true)]
3public Guid NEWID()
4{
5    return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
6}
7
8//在使用中
9var customer = (from c in ctx.Customers orderby ctx.NEWID()).First();

参考:http://www.cnblogs.com/Mirricle/archive/2007/08/16/858260.html

可惜它是linq to sql,我没办法在.edmx下找到通用的做法,而且据说一旦更新了model,整个修改又被覆盖。我总不可能每次修改就复制一次吧?

 

第二种方式是:

   (from p in db.Products).OrderBy(e => Guid.NewGuid()).Take(10);
 但是在linq to entity 的时候就报错!linq to entities 没有啥Guid.NewGuid()这类的鸟方法。又行不通。

参考:http://www.cnblogs.com/hanxianlong/archive/2007/11/06/951462.html

 

第三种方式是在鸟语论坛上找到的:

You can do it with ESql

model.CreateQuery<Products>(  
@"Select VALUE source.entity
  From (Select entity, SqlServer.NewID() as rand
        From Products as entity) as source
  Order by source.rand"); 

on this code you can use Take(20) to get a list of random items, or you can just add "Top 20" to the select statement

参考:http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/9d41ee63-8656-4bc5-875e-3ef8dd3d8ee9

我照着敲,运行的时候报错,还是行不通。

 

第四种方式是:

First, create the following view:

CREATE VIEW RandomView
AS
SELECT NEWID() As ID

Then create the following function that uses the view:

CREATE FUNCTION GetNewId
(
)
RETURNS uniqueidentifier
AS
BEGIN
RETURN (SELECT ID FROM RandomView)
END

The view is required because it's not possible to directly use NEWID in a scalar function.

You can then map the GetNewId user-defined function using LINQ to SQL's Function attribute. Again, see chapter 8 for the details.

That's it! You can now write LINQ queries as usual. Here is an example to pick a random object:

var tool = db.Tools.OrderBy(t => db.GetNewId()).First()

Here is another example that uses GetNewId to sort results randomly: 

var tools =
  from tool in db.Tools
  orderby db.GetNewId()
  select tool.Name;

参考:http://crazythief.com/KB/496509ca-6231-473b-b9c8-6bd87fc607ec

依然照着做了遍,然后屁颠屁颠的更新模型,然后去找,就是找不到GetNewId()这个鸟方法。

  

本来以为是无望了,结果回来问了下rei,他说要写个IComparer,但是我这个菜鸟根本不知道怎么写,只要问有没有简单点的?我就问视图怎么样?结果他告诉我可以用第五种方法。

 

第五种方法:

  添加视图- create view MyView as  select t.*, newid() as r from MyTable  t order by r;

  调用方法- var query = from q in context.MyView select q;

  执行转换- xxxxxxxx.

 

   ok,困扰了一天的事情总算解决了,继续将我的毕业设计进行下去。。。

posted @   idoku  阅读(1786)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示