随机条件

时间:2017-01-06 10:56:23

标签: c# asp.net algorithm

我有以下代码使用dbcontext类随机从Guid中提取记录:

var CategoryList = {1,5};
var generatedQues = new List<Question>();

//Algorithm 1 :)
if (ColNum > 0)
   {
    generatedQues = db.Questions
          .Where(q => CategoryList.Contains(q.CategoryId))
          .OrderBy(q => Guid.NewGuid()).Take(ColNum).ToList();
   }

首先,我在CategoryId中存储了一个CategoryList列表,作为从db获取记录时要完成的条件。但是,我希望在基于CategoryId的问题中实现均匀分布。

例如:

如果ColNum为10,而获得的CategoryId{1,5},我希望通过获取来自CategoryId = 1的5条记录和另一组5条来实现来自CategoryId = 5的记录。如果ColNum是一个像11这样的奇数,我也希望尽可能地实现均匀分布,例如从CategoryId 1得到5条记录,从CategoryId 2得到6条记录。

我该怎么做?

2 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

var CategoryList = {1,5};
var generatedQues = new List<Question>();

//Algorithm 1 :)
if (ColNum > 0 && CategoryList.Count > 0)
{
    var take = // Calculate how many of each
    // First category
    var query = db.Questions
            .Where(q => q.CategoryId == CategoryList[0])
            .OrderBy(q => Guid.NewGuid()).Take(take);

    // For all remaining categories
    for(int i = 1; i < CategoryList.Count; i++)
    {
        // Calculate how many you want
        take = // Calculate how many of each
        // Union the questions for that category to query
        query = query.Union(
            query
            .Where(q => q.CategoryId == CategoryList[i])
            .OrderBy(q => Guid.NewGuid()).Take(take));
    }
    // Randomize again and execute query
    generatedQues = query.OrderBy(q => Guid.NewGuid()).ToList()
}

我们的想法是为每个类别获取一个随机列表,并将它们全部加在一起。然后你再次随机化并创建你的列表。我不知道它是否会在数据库或内存中完成所有这些,但我认为它应该是数据库。结果SQL看起来很糟糕。

答案 1 :(得分:0)

这是一个两步过程,

  1. 确定每个类别的数量
  2. 以随机顺序从每个类别中选择多个项目
  3. 对于第一部分,定义一个类来表示类别以及需要多少项

    public class CategoryLookup
    {
    
        public CategoryLookup(int catId)
        {
            this.CategoryId = catId;
        }
    
        public int CategoryId
        {
            get; private set;
        }
    
        public int RequiredAmount
        {
            get; private set; 
        }
    
        public void Increment()
        {
            this.RequiredAmount++;
        }
    }
    

    然后,根据您对所需类别和所需项目总数的输入,计算出每个类别需要的数量

     var categoryList = new []{1,5};
     var colNum = 7;
    
     var categoryLookup = categoryList.Select(x => new CategoryLookup(x)).ToArray();
     for(var i = 0;i<colNum;i++){
         categoryLookup[i%categoryList.Length].Increment();
     }
    

    第二部分是真的简单,只需使用SelectMany来获取问题列表(我已经使用直接linq来测试对象,应该适用于数据库查询。{ {1}}在我的代码中只有questions在你的代码中

    db.Questions

    实例:http://rextester.com/RHF33878