c# - 在linq中使用where子句选择随机问题

标签 c# linq linq-to-sql

我需要为每个类别选择随机问题

private int[] categoryId = {1, 2, 3, 4, 5, ...};
private int[] questionsPerCategory = {3, 1, 6, 11, 7, ...};

在linq之前我是通过使用实现的

SELECT TOP (@questionsPerCategory) * From Questions WHERE CategoriesID = @categoryId  AND 
InTest ='1' ORDER BY NEWID()

这也不正确,因为我必须为每个 categoryId 调用它。

如何在单个查询中使用 linq 获得所需的结果? 我只需要获取

  • 3 个随机问题,categoryId = 1 且 InTest = true,
  • 1 个随机问题,categoryId = 2 且 InTest = true,
  • 6 个随机问题,categoryId = 3 且 InTest = true

等等..

最佳答案

由于 LINQ to SQL 不支持 Guid.NewGuid,首先您需要使用 Random row from Linq to Sql 的已接受答案中的技巧来访问 NEWID 函数通过将以下内容添加到您的上下文类中:

partial class YourDataContext {
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}

那么对单个 CategoryID 和问题计数的查询将是:

var query = db.Questions
    .Where(e => e.CategoriesID == categoryId[i] && e.InTest)
    .OrderBy(e => db.Random())
    .Take(questionsPerCategory[i])

要获得所有类别/问题计数对的所需结果,您可以使用上述单个查询的 Concat 构建一个 UNION ALL SQL 查询 i = 0..N 像这样:

var query = categoryId.Zip(questionsPerCategory,
    (catId, questions) => db.Questions
        .Where(q => q.CategoriesID == catId && q.InTest)
        .OrderBy(q => db.Random())
        .Take(questions)
    ).Aggregate(Queryable.Concat)
    .ToList();

这应该会通过单个 SQL 查询产生所需的结果。当然如果categoryId的个数比较少也是可以的。

关于c# - 在linq中使用where子句选择随机问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45630328/

相关文章:

c# - 使用 LINQ 查询自动检查 NULL 关系

c# - 解析日期字符串以获取年份

c# - 如何把这个 Func 变成一个表达式?

c# - 选择子句为空

sql-server - linq to sql 何时会被淘汰? Entity Framework (替代)发布了吗?

c# - 在 C# 中使用 LINQ 自动递增通用列表

c# - 如何使用 SqlFunctions.DateName 获取小时部分

c# - 在 Telerik Radgrid 中,如何根据组标题的数量对结果进行分页?

c# - 我们如何在 Automation Anywhere 中使用 pgSQL?

c# - 优化 LINQ 查询