【问题标题】:c# Randomize DataTable rowsc# 随机化 DataTable 行
【发布时间】:2015-11-02 15:49:13
【问题描述】:

我有一个数据表用作中继器的数据源,并且希望每次调用时都以随机顺序显示结果。

我已经能够在检索数据时执行此操作,但希望在绑定之前缓存结果集。

在绑定到中继器之前是否要对数据表的行进行洗牌或随机化?

代码:

        TreeProvider tp = new TreeProvider();
    DataSet ds = new DataSet();
    string sKey = "KEY";
    using (CachedSection<DataSet> cs = new CachedSection<DataSet>(ref ds, 5, true, null, sKey))
    {
      if (cs.LoadData)
      {
        ds = tp.SelectNodes("", "URL", "", true, "DOCTYPE", "", "NewID()", -1, true, 5);
        cs.Data = ds;
      }
    }
    if (!DataHelper.DataSourceIsEmpty(ds))
    {
      rprItems.DataSource = ds.Tables[0].DefaultView;
      rprItems.DataBind();
    }

感谢任何指导。

【问题讨论】:

  • 您可以将目前的代码添加到问题中吗?
  • 觉得没有必要,因为它是通用的。现在添加...
  • 这是一个可能对你有帮助的链接social.msdn.microsoft.com/Forums/en-US/…
  • 这不是您从 SQL 中引入的 NewID() 列的重点吗?你不是在SQL语句中按那个排序来随机化行顺序吗?
  • 文森特詹姆斯是和不是。这确实使它随机化,但就像我说的那样,我正在缓存数据,所以它只是每 5 分钟随机一次。每次设置数据源时,我都需要它是随机的。

标签: c# datatable datasource repeater


【解决方案1】:

我最终复制了表格,添加了一个字段并为每一行分配一个随机数,然后按该行排序。

        DataTable dt = ds.Tables[0].Copy();
        if (!dt.Columns.Contains("SortBy"))
          dt.Columns.Add("SortBy", typeof (Int32));

        foreach (DataColumn col in dt.Columns)
          col.ReadOnly = false;

        Random rnd = new Random();
        foreach (DataRow row in dt.Rows)
        {
          row["SortBy"] = rnd.Next(1, 100);
        }
        DataView dv = dt.DefaultView;
        dv.Sort = "SortBy";
        DataTable sortedDT = dv.ToTable();

        rprItems.DataSource = sortedDT;
        rprItems.DataBind();

【讨论】:

    【解决方案2】:

    你可以试试这样的东西,我知道它不漂亮但是:

    DataTable newTable = new DataTable();
    newTable.TableName = "<NewTableName>";
    //Make a new Random generator
    Random rnd = new Random();
    while (<new table length> != <old table length>)
    {
        //We'll use this to make sure we don't have a duplicate row
        bool rowFound = false;
        //index generation
        int index = rnd.Next(0, <max number of rows in old data>);
        //use the index on the old table to get the random data, then put it into the new table.
        foreach (DataRow row in newTable.Rows)
        {
            if (oldTable.Rows[index] == row)
            {
                //Oops, there's duplicate data already in the new table. We don't want this.
                rowFound = true;
                break;
            }
        }
        if (!rowFound)
        {
            //add the row to newTable
            newTable.Rows.Add(oldTable.Rows[index];
        }
    }
    

    当然,您必须使用自己的表格、名称和长度,但这应该没问题。如果有很多数据,这可能需要一段时间。这是我能想到的最好的,而且未经测试。我很想知道它是否有效。

    【讨论】:

    • 随机类是伪随机数生成器,它永远不会产生真正的随机数
    • 我不知道任何其他的随机方式。到目前为止,每个答案都有类似的建议。
    • 检查我的答案,它没有,它引用了使用 System.Cryptography 的真随机数生成器
    • 我将 Random 和您的自定义 Random 放入一个程序并对其进行了测试。我看到的唯一区别是 Random 只能初始化一次,或者您多次获得相同的数字,而您的可以一遍又一遍地初始化,并且可能具有相同的数字,但不太可能。好东西。
    • RNGCryptoServiceProvider 在我的示例中使用,能够生成真正的随机数,即使使用相同的对象和种子,也不需要每次都使用新对象,相对于 Random 类,它会在一段时间后开始重复数字/迭代由于其伪性质
    【解决方案3】:

    你可以试试:

            DataTable dt = new DataTable();
            dt.Columns.Add("Name");
            dt.Columns.Add("Sort");
            dt.Rows.Add("TEST");
            dt.Rows.Add("TEST1");
            dt.Rows.Add("TEST2");
    
            var rnd = new Random(DateTime.Now.Millisecond);
            foreach (DataRow row in dt.Rows)
            {
                row["Sort"] = rnd.Next(dt.Rows.Count);
            }
    
    
            var dv = new DataView(dt);
            dv.Sort = "Sort";
            foreach (DataRowView row in dv)
            {
                Console.WriteLine(row[0]);
            }
    

    如果你的数据表不是太大,它应该这样做。

    【讨论】:

    • 随机类是伪随机数生成器,它永远不会产生真正的随机数
    • 您可以随意替换。将排序列更改为 guid 并生成新的 Guid 将执行与 SQL 相同的技巧。请记住,到目前为止我们不需要生成唯一的随机数,这个想法只是随机排序结果。除非您需要复杂的解决方案,否则请保持简单
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多