如何从数据库中获取随机行,以便它们在多次调用中不会重复

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