如何在linq中获取随机行,最后一行插入行

时间:2015-06-10 09:33:09

标签: linq entity-framework random linq-to-sql shuffle

我正在尝试针对每个请求显示随机产品,this OrderBy(r => Guid.NewGuid())工作正常,但我正在尝试在表记录很大时提高性能,所以我使用了来自{{的第二个选项3}}

我的行动:

public ActionResult ProductType(string id)
{
List<ProductsView> productlist = (from a in this.dbo.ProductTable
                                 join ca in dbo.Category on a.CategoryID equals ca.CategoryID
                                 where ca.Category == id 
                                 select new ProductsView()
                                 {
                                 CategoryID = c.CategoryID,
                                 Categorycount = c.Categorycount
                                 }).ToList<ProductsView>();

// here shuffle or mix products

int count = productlist.Count();
int index = new Random().Next(count);
ViewBag.Products = productlist.Skip(index).ToList();

 return View();

}

但是当视图返回时,一些记录丢失,例如:

第一次请求 数4 指数1

在视图中显示3个产品

第二次请求 数4 指数2

在视图中显示2个产品

第三次请求 数4 指数3

在视图中显示1个产品

最后我还有一个要求,我可以在顶部显示最后插入的行,让其他产品是随机的吗?

我可能知道自己错过了什么吗?

任何帮助都会很棒。

1 个答案:

答案 0 :(得分:1)

好的,所以更新的要求是:

  • 获取所有项目
  • 订购是第一项以外的随机订单,应该是添加的最后一项

首先,摆脱你的Skip电话。你不想跳过任何东西。只需将所有产品(可能已订购 - 见下文)提取到列表中。

对于随机性部分,我在调用代码中使用修改后的Fischer-Yates shuffle来做到这一点 - Stack Overflow上有很多例子,例如here

在这种情况下,您可能希望将最新项目放到列表的开头,然后只是将列表的 rest 洗牌。只需稍微修改一下洗牌代码就可以了 - 但是你需要先将最新的项目放到列表的开头。您可以通过在LINQ查询中使用OrderByDescending(x => x.InsertionDate)(或其他)来执行此操作,或者只是获取所有内容并在内存中的行上通过O(n)传递查找最新行。使用OrderByDescending会更简单,但可能效率稍低(因为您并不需要完全订购)。