Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 选择linq中带有where子句的随机问题_C#_Linq_Linq To Sql - Fatal编程技术网

C# 选择linq中带有where子句的随机问题

C# 选择linq中带有where子句的随机问题,c#,linq,linq-to-sql,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

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

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()
这也是不正确的,因为我必须对每个类别都这样称呼

如何在单个查询中使用linq获得所需的结果? 我所需要的就是去拿

  • 3个随机问题,categoryId=1,InTest=true
  • 1个随机问题,categoryId=2,InTest=true
  • 6个随机问题,类别ID=3,InTest=true

等等..

我想您正在寻找Take()方法。 您还应该将参数传递给具有类别id的方法,以及您希望接收的问题数量。从数组中传递这些参数

private IQuerable<Question> Method(int Id, int questionsCount)
{    
return Questions.Where(c=>c.CategoriesId==Id && c.InTest==1).Take(questionsCount).OrderBy(c=>c.NewId);
}
private iquirable方法(int-Id,int-questionscont)
{    
返回问题。其中(c=>c.CategoriesId==Id&&c.InTest==1)。接受(questionsCount)。OrderBy(c=>c.NewId);
}

一种常见的方法是按
Guid.NewGuid()
排序,以便扩展上面Crekate的答案

.OrderBy(c=>Guid.NewGuid());

也许你想要这样的东西,你做一个小组,然后从每个类别中选择你想要的数量

已编辑:正如注释中的Enigmativity所指出的,Guid.NewGuid()不应用于表示随机性,而仅用于表示唯一性。要产生随机性,你应该参考

使用系统;
使用System.Linq;
使用System.Collections.Generic;
公共课程
{
私有静态int[]categoryId=新int[]{1,2,3,4,5};
私有静态int[]问题分类={3,1,6,11,7};
//演示的一部分
私有静态IEnumerable Questions=Enumerable.Range(0100)。选择(x=>newQuestionVM{Question=$“Question-{x}”,CategoryId=(x%5)+1});
公共静态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问题)
Console.WriteLine($“{question.question}-CategoryId:{question.CategoryId}”);
}
///通过执行搜索,然后在相同位置选择元素,找出它应该回答多少问题
私有静态int GetQuestionTake(int categoryId)
{
int element=categoryId.Select((x,i)=>new{i,x}).FirstOrDefault(x=>x.x==categoryId.i;
返回问题分类.elementatorderfault(element);
}
}
//演示的一部分
公开课问题
{
公共字符串问题{get;set;}
public int CategoryId{get;set;}
公共bool InTest{get;set;}=true;
}

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

partial class YourDataContext {
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}
然后,对单个
类别ID
和问题计数的查询将是:

var query = db.Questions
    .Where(e => e.CategoriesID == categoryId[i] && e.InTest)
    .OrderBy(e => db.Random())
    .Take(questionsPerCategory[i])
要获得所有类别/问题计数对的所需结果,您可以使用上述单个查询的
Concat
i=0..N
构建一个
UNION all
SQL查询,如下所示:

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的计数相对较小,则它是适用的。

运算符“==”不能应用于“int”类型的操作数,并且“int[]”选中了它。它仍然在抱怨。无法从“int”转换为“System.Func”。我们不知道您的属性是什么数据类型。InTest是一个布尔吗?然后删除“==1”。在任何()函数中都是我的错误。请检查一下now@DanielForslund正如我所发布的,问题是c=>categoryId.Any(c.CategoriesId)不在“InTest”列中。因此,我将从查询中删除'InTest'列,因为语法错误。
Questions
表是什么样子的?“random”到底是什么意思?@JakubDąbek在其他列中有categoriseId和intestThank Daniel,问题是在这个c=>categoryId.Any(c.categoriseId)中无法从“int”转换为“System.Func”,它可以正常工作,但不幸的是,如果我添加.ToList()之前。选择Many我将得到所有问题,然后调用GetQuestionTake方法。这是真的还是我遗漏了什么?如果你做一个.ToList()它会把所有的东西都拉出来。每个类别id都会调用GetQuestionTake方法,如果您不喜欢GetQuestionTake方法,我建议将CategoryId和questionsPerCategory转换为另一种类型,如字典。不幸的是,如果我不首先调用.ToList(),GetQuestionTake将不会转换为SQL。改用字典我能得到什么?我不明白事实上我恐怕没有一个数据库来测试这个,但是我在想这样的事情(它可能不起作用),@Shoejep-不,它不依赖于应用程序。如果.NET framework得到更新,则可以从明天开始按顺序生成GUI。只要它们是全球独一无二的,那就好了。如果需要随机顺序,则不应选择Guid。现在,您提供的链接是一个完全不同的东西-如果数据库中的
NEWID
是随机的,那么这很好,但是.NET中的
Guid.NewGuid()
不能保证是随机的。
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();