我需要为每个类别选择随机问题
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获得所需的结果? 我需要的只是获取
依旧......
答案 0 :(得分:3)
也许你想要这样的东西,你做一个小组然后从每个类别中选择你想要多少。
编辑:正如评论中的Enigmativity所指出的,Guid.NewGuid()不应仅仅因为唯一性而被用于随机性。要产生随机性,您应该咨询this StackOverflow post。
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
private static int[] categoryIds = new int[] {1, 2, 3, 4, 5};
private static int[] questionsPerCategory = {3, 1, 6, 11, 7};
//Part of demo
private static IEnumerable<QuestionVM> Questions = Enumerable.Range(0,100).Select(x=> new QuestionVM { Question = $"Question - {x}", CategoryId = (x % 5) + 1});
public static void Main()
{
var questions = Questions.Where(x=> x.InTest).GroupBy(x=> x.CategoryId).SelectMany(x=> x.OrderBy(y=> Guid.NewGuid()).Take(GetQuestionTake(x.Key)));
foreach(var question in questions)
Console.WriteLine($"{question.Question} - CategoryId: {question.CategoryId}");
}
///Finds out how many questions it should take by doing a search and then picking the element in the same position
private static int GetQuestionTake(int categoryId)
{
int element = categoryIds.Select((x, i) => new { i, x }).FirstOrDefault(x => x.x == categoryId).i;
return questionsPerCategory.ElementAtOrDefault(element);
}
}
//Part of demo
public class QuestionVM
{
public string Question {get;set;}
public int CategoryId {get;set;}
public bool InTest {get;set;} = true;
}
答案 1 :(得分:3)
由于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])
和问题计数将是:
UNION ALL
要获得所有类别/问题计数对的预期结果,您可以使用上述Concat
i = 0..N
的{{1}} 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();
来构建categoryId
SQL查询:
import { trigger, animate, style, group, query, transition } from '@angular/animations';
export const baseAnimation =
trigger('baseAnimation', [
transition('acct => home', [
query(':enter, :leave', style({ position: 'absolute', top: 0, left: 0, right: 0 })),
query(':leave', style({ height: '*'})),
query('.acct', [
animate('300ms',
style({ height: 0 }))
])
]),
transition('home => acct', [
query(':enter, :leave',
style({ position: 'absolute', top: 0, left: 0, right: 0 })),
query(':enter .acct', [
style({ height: 0 }),
animate('300ms', style({ height: '*' }))
])
])
])
这应该通过单个SQL查询产生所需的结果。当然,如果.acct
的计数相对较小,它是适用的。
答案 2 :(得分:0)
一种常见的方式是按Guid.NewGuid()
排序,以便扩展Crekate的答案。
.OrderBy(c=>Guid.NewGuid());