EF Code First:如何获取随机行

Mel*_*Mel 68 c# entity-framework ef-code-first entity-framework-4.1

如何构建一个查询随机行的查询?

如果我在SQL中编写它,那么我会在newid()上输入一个命令并从顶部删除n行.无论如何要先在EF代码中执行此操作?

我尝试创建一个使用newid()并使用DbSet.SqlQuery()执行它的查询.虽然它有效,但它不是最干净的解决方案.

此外,尝试检索所有行并通过新guid对它们进行排序.尽管行数相当小,但它仍然不是一个好的解决方案.

有任何想法吗?

SLa*_*aks 144

只需致电:

something.OrderBy(r => Guid.NewGuid()).Take(5)
Run Code Online (Sandbox Code Playgroud)

  • 看到[这个问题](http://stackoverflow.com/q/7952147/1178314),遗憾的是它被打破了.看起来`OrderBy`假设排名函数是稳定的,而随机生成器不是这种情况.Linq to entities将其转换为sql查询,该查询可能会为同一实体获得不同的排名(只要您的查询使用"Include").然后它会导致实体在结果列表中重复. (3认同)
  • 从 .NET 5 开始,这会在使用 include 时导致奇怪的行为 (2认同)

drz*_*aus 33

比较两个选项:


跳过(随机行数)

方法

private T getRandomEntity<T>(IGenericRepository<T> repo) where T : EntityWithPk<Guid> {
    var skip = (int)(rand.NextDouble() * repo.Items.Count());
    return repo.Items.OrderBy(o => o.ID).Skip(skip).Take(1).First();
}
Run Code Online (Sandbox Code Playgroud)
  • 需要2个查询

生成的SQL

SELECT [GroupBy1].[A1] AS [C1]
FROM   (SELECT COUNT(1) AS [A1]
        FROM   [dbo].[People] AS [Extent1]) AS [GroupBy1];

SELECT TOP (1) [Extent1].[ID]            AS [ID],
               [Extent1].[Name]          AS [Name],
               [Extent1].[Age]           AS [Age],
               [Extent1].[FavoriteColor] AS [FavoriteColor]
FROM   (SELECT [Extent1].[ID]                                  AS [ID],
               [Extent1].[Name]                                AS [Name],
               [Extent1].[Age]                                 AS [Age],
               [Extent1].[FavoriteColor]                       AS [FavoriteColor],
               row_number() OVER (ORDER BY [Extent1].[ID] ASC) AS [row_number]
        FROM   [dbo].[People] AS [Extent1]) AS [Extent1]
WHERE  [Extent1].[row_number] > 15
ORDER  BY [Extent1].[ID] ASC;
Run Code Online (Sandbox Code Playgroud)

GUID

方法

private T getRandomEntityInPlace<T>(IGenericRepository<T> repo) {
    return repo.Items.OrderBy(o => Guid.NewGuid()).First();
}
Run Code Online (Sandbox Code Playgroud)

生成的SQL

SELECT TOP (1) [Project1].[ID]            AS [ID],
               [Project1].[Name]          AS [Name],
               [Project1].[Age]           AS [Age],
               [Project1].[FavoriteColor] AS [FavoriteColor]
FROM   (SELECT NEWID()                   AS [C1],
               [Extent1].[ID]            AS [ID],
               [Extent1].[Name]          AS [Name],
               [Extent1].[Age]           AS [Age],
               [Extent1].[FavoriteColor] AS [FavoriteColor]
        FROM   [dbo].[People] AS [Extent1]) AS [Project1]
ORDER  BY [Project1].[C1] ASC
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的比较,确实有帮助 (2认同)

Utt*_*eja 28

ef core 6 + 有一个新函数:EF.Functions.Random()

something.OrderBy(r => EF.Functions.Random()).Take(5)
Run Code Online (Sandbox Code Playgroud)