简体   繁体   English

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

[英]C# - How to select distinct random records from datatable

I am trying to fetch records from DataTable randomly with some limit. 我试图从DataTable中随机获取记录,但有一些限制。 I am able to fetch the data randomly as follows - 我可以按以下方式随机获取数据-

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

But the values seems to be redundant. 但是这些值似乎是多余的。 I want to get the unique values. 我想获得独特的价值。 So far I have tried Distinct() as - 到目前为止,我已经尝试将Distinct()设置为-

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

But that doesn't seems to be worked out. 但这似乎没有解决。 Can anybody please guide where am going wrong with this. 谁能指导这出什么问题了。 Thanks. 谢谢。

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

In ToTable method the first parameter specifies if you want Distinct records, the second specify by which column name we will make distinct. ToTable方法中,第一个参数指定是否要使用Distinct记录,第二个参数指定要Distinct哪个列名。

After that if you want to take some number of it you can do 之后,如果您想服用一些,可以

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

If you want unique records according to one column: 如果要根据一列进行唯一记录:

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

If you want unique records according to multiple columns, use an anonymous type: 如果要根据多个列创建唯一记录,请使用匿名类型:

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();

if you want a dynamic way to compare all columns even if you don't know them: 如果您想要一种动态的方式来比较所有列,即使您不知道它们,也可以:

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());
    }
}

Usage: 用法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM