我正在尝试针对每个请求显示随机产品,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个产品
最后我还有一个要求,我可以在顶部显示最后插入的行,让其他产品是随机的吗?
我可能知道自己错过了什么吗?
任何帮助都会很棒。
答案 0 :(得分:1)
好的,所以更新的要求是:
首先,摆脱你的Skip
电话。你不想跳过任何东西。只需将所有产品(可能已订购 - 见下文)提取到列表中。
对于随机性部分,我在调用代码中使用修改后的Fischer-Yates shuffle来做到这一点 - Stack Overflow上有很多例子,例如here。
在这种情况下,您可能希望将最新项目放到列表的开头,然后只是将列表的 rest 洗牌。只需稍微修改一下洗牌代码就可以了 - 但是你需要先将最新的项目放到列表的开头。您可以通过在LINQ查询中使用OrderByDescending(x => x.InsertionDate)
(或其他)来执行此操作,或者只是获取所有内容并在内存中的行上通过O(n)传递查找最新行。使用OrderByDescending
会更简单,但可能效率稍低(因为您并不需要完全订购)。