(перекрестная публикация из EF Code First: как получить случайные строки )
Сравнение двух вариантов:
Пропустить (случайное количество строк)
Метод
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();
}
Сгенерированный 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;
Guid
Метод
private T getRandomEntityInPlace<T>(IGenericRepository<T> repo) {
return repo.Items.OrderBy(o => Guid.NewGuid()).First();
}
Сгенерированный 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
Таким образом, в более новом EF вы снова можете увидеть, что NewGuid
переведено в SQL (что подтверждается @DrewNoakes https://stackoverflow.com/a/4120132/1037948). Несмотря на то, что оба метода "in-sql", я предполагаю версию Guid быстрее? Если вам не нужно было сортировать их, чтобы пропустить, и вы могли бы разумно угадать количество пропущенных, то, возможно, метод пропуска будет лучше.