C# - 如何从数据表中选择不同的随机记录

时间:2016-07-26 09:53:33

标签: c# winforms linq random datatable

我正在尝试从DataTable中随机获取一些限制的记录。我能够随机获取数据 -

 var r = new Random();
 var _randomSelection = dt.Rows.OfType<DataRow>().OrderBy(rand => r.Next()).Take(limit);

但价值似乎是多余的。我想获得独特的价值观。到目前为止,我已尝试将 Distinct()作为 -

var _randomSelection = dt.Rows.OfType<DataRow>().OrderBy(rand => r.Next()).Take(limit).Distinct();

但这似乎并没有解决。任何人都可以指导哪里出错了。感谢。

2 个答案:

答案 0 :(得分:1)

   DataTable returnVals = dt.DefaultView.ToTable(true, "ColumnNameOnWhichYouWantDistinctRecords");

ToTable方法中,第一个参数指定是否需要Distinct个记录,第二个参数指定我们将使哪个列名称不同。

之后,如果你想要一些,你可以做

var result = returnVals.Rows.Cast<DataRow>().OrderBy(rand => r.Next()).Take(number);

答案 1 :(得分:0)

如果您想要根据一列的唯一记录:

var distinctRows = from r in table.AsEnumerable()
                   let id = r.Field<int>("Id")
                   group r by id into idGroup
                   select idGroup.First();

如果您想根据多个列创建唯一记录,请使用匿名类型:

var distinctRows = from r in table.AsEnumerable()
                   let keyCols = new { id=  r.Field<int>("Id"), col2 = r.Field<string>("Col2")}
                   group r by keyCols into keyGroup
                   select keyGroup.First();

如果您想要一种动态方式来比较所有列,即使您不了解它们:

public static class DataTableExtensions
{
    public class DataRowValuesComparer : IEqualityComparer<DataRow>
    {
        public bool Equals(DataRow x, DataRow y)
        {
            if(ReferenceEquals(x, y))
                return true;
            if (x == null || y == null)
                return false;
            if (!ReferenceEquals(x.Table, y.Table))
                return false; // different tables
            foreach (DataColumn column in x.Table.Columns)
            {
                object v1 = x[column];
                object v2 = y[column];
                if (ReferenceEquals(v1, v2)) continue;
                if (v1 == null || v2 == null) return false;
                if (!v1.Equals(v2)) return false;
            }
            return true;
        }

        public int GetHashCode(DataRow obj)
        {
            if (obj == null) return int.MinValue;
            unchecked
            {
                int hash = 19;
                foreach (DataColumn column in obj.Table.Columns)
                {
                    object value = obj[column];
                    hash = hash * 31 + (value?.GetHashCode() ?? 0);
                }
                return hash;
            }
        }
    }

    public static IEnumerable<DataRow> DistinctValues(this IEnumerable<DataRow> rows)
    {
        return rows.Distinct(new DataRowValuesComparer());
    }
}

用法:

var distinctRows = table.AsEnumerable().DistinctValues();