如何从数据库中获取随机行,以便它们在多次调用中不会重复
How to take random rows from database, so that they are not duplicated, throughout multiple calls
问题是:
我正在使用 C# + EF,我需要随机抽取 20 个条目。
在每次下一次调用之后,我需要再添加 20 个随机条目,但这些条目未包含在之前的任何函数调用中。
有什么方法可以根据种子生成 GUID,以便在所有调用中生成相同的 GUID?
不能使用,前提是不能保持连接
正如我在评论中所说,您可以简单地保持打开对数据库的查询,而不关闭它。您阅读了 20 行,return 它们同时保持打开 reader/ienumerable,然后根据要求阅读接下来的 20 行,依此类推。
public IEnumerable<YourObject[]> GetRows()
{
using (var connection = new SqlConnection())
{
var command = connection.CreateCommand();
command.CommandText = "select * from [yourtable] order by newid()";
using (var reader = command.ExecuteReader())
{
var lst = new List<YourObject>(20);
while (true)
{
for (int i = 0; i < 20; i++)
{
if (!reader.Read())
{
break;
}
var obj = new YourObject();
// Read your row
lst.Add(obj);
}
if (lst.Count == 0)
{
break;
}
// Micro-optimization: we don't keep two copies
// of the lst after the yield
bool last = lst.Count != 20;
var array = lst.ToArray();
lst.Clear();
yield return array;
if (last)
{
break;
}
}
}
}
}
如果您必须多次执行查询,则不能按 newid()
排序,因为它是随机的,下次执行不会有相同的结果。
所以你需要有一个伪随机值。哈希是一种伪随机值。让我们按哈希值排序。
DECLARE @randomKey nvarchar(max) = 'randomValue';
SELECT *,
HASHBYTES('SHA1', @randomKey + cast(rowId as nvarchar(max))) as [Order]
FROM dbo.Table
ORDER BY [Order] DESC
OFFSET 5 ROWS
FETCH NEXT 5 ROWS ONLY
使用此代码,结果将随机按@randomKey
排序。
为了让Entity Framework为你生成HashBytes
调用,不用写T-SQL。你可以看看这个项目:Store Functions for Entity Framework Code First
问题是: 我正在使用 C# + EF,我需要随机抽取 20 个条目。 在每次下一次调用之后,我需要再添加 20 个随机条目,但这些条目未包含在之前的任何函数调用中。 有什么方法可以根据种子生成 GUID,以便在所有调用中生成相同的 GUID?
不能使用,前提是不能保持连接
正如我在评论中所说,您可以简单地保持打开对数据库的查询,而不关闭它。您阅读了 20 行,return 它们同时保持打开 reader/ienumerable,然后根据要求阅读接下来的 20 行,依此类推。
public IEnumerable<YourObject[]> GetRows()
{
using (var connection = new SqlConnection())
{
var command = connection.CreateCommand();
command.CommandText = "select * from [yourtable] order by newid()";
using (var reader = command.ExecuteReader())
{
var lst = new List<YourObject>(20);
while (true)
{
for (int i = 0; i < 20; i++)
{
if (!reader.Read())
{
break;
}
var obj = new YourObject();
// Read your row
lst.Add(obj);
}
if (lst.Count == 0)
{
break;
}
// Micro-optimization: we don't keep two copies
// of the lst after the yield
bool last = lst.Count != 20;
var array = lst.ToArray();
lst.Clear();
yield return array;
if (last)
{
break;
}
}
}
}
}
如果您必须多次执行查询,则不能按 newid()
排序,因为它是随机的,下次执行不会有相同的结果。
所以你需要有一个伪随机值。哈希是一种伪随机值。让我们按哈希值排序。
DECLARE @randomKey nvarchar(max) = 'randomValue';
SELECT *,
HASHBYTES('SHA1', @randomKey + cast(rowId as nvarchar(max))) as [Order]
FROM dbo.Table
ORDER BY [Order] DESC
OFFSET 5 ROWS
FETCH NEXT 5 ROWS ONLY
使用此代码,结果将随机按@randomKey
排序。
为了让Entity Framework为你生成HashBytes
调用,不用写T-SQL。你可以看看这个项目:Store Functions for Entity Framework Code First