如何在数据表中获取不同的记录?

时间:2010-07-20 15:41:44

标签: c# asp.net .net visual-studio-2008 ado.net

我正在使用C#+ VS2008 + .Net + ASP.Net + IIS 7.0 + ADO.Net + SQL Server 2008.我有一个ADO.Net数据表对象,我想过滤掉重复/类似的记录(在我的判断记录是否重复/类似的特定规则 - 如果记录/行对于字符串列具有相同的值,我会将它们视为重复/类似记录),并且只保留其中一个重复/类似记录。

输出需要是数据表,如果可以在同一个数据表对象上操作过滤操作,则可以输出相同的数据表对象。

什么是最有效的解决方案?

3 个答案:

答案 0 :(得分:2)

您使用的是.NET 3.5吗?如果转换数据行,则可以使用LINQ to Objects:

var distinctRows = table.Rows.Cast<DataRow>().Distinct(new E());

...

public class E : IEqualityComparer<DataRow>
{
    bool IEqualityComparer<DataRow>.Equals(DataRow x, DataRow y)
    {
        return x["colA"] == y["colA"];
    }

    int IEqualityComparer<DataRow>.GetHashCode(DataRow obj)
    {
        return obj["colA"].GetHashCode();
    }
}

或者更简单的方法,因为您将它基于单个列的值:

var distinct = from r in table.Rows.Cast<DataRow>()
               group r by (string)r["colA"] into g
               select g.First();

如果您需要从这些不同的行中创建一个新的DataTable,您可以这样做:

var t2 = new DataTable();
t2.Columns.AddRange(table.Columns.Cast<DataColumn>().ToArray());
foreach(var r in distinct)
{
    t2.Rows.Add(r);
}

或者,如果使用业务对象会更方便,您可以轻松转换:

var persons = (from r in distinct
               select new PersonInfo
               {
                   EmpId = (string)r["colA"],
                   FirstName = (string)r["colB"],
                   LastName = (string)r["colC"],
               }).ToList();

...

public class PersonInfo
{
    public string EmpId {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

更新

你可以在没有它的情况下完成LINQ to Objects所能做的一切:它只需要更多的代码。例如:

var table = new DataTable();
var rowSet = new HashSet<DataRow>(new E());
var newTable = new DataTable();
foreach(DataColumn column in table.Columns)
{
    newTable.Columns.Add(column);
}
foreach(DataRow row in table.Rows)
{
    if(!rowSet.Contains(row))
    {
        rowSet.Add(row);
        newTable.Rows.Add(row);
    }
}

您还可以使用类似的策略从原始表中删除重复的行,而不是创建新表。

答案 1 :(得分:1)

您可以使用select into子句执行group by,因此不会创建重复项。然后删除旧表并将您选择的表重命名为原始表名。

答案 2 :(得分:1)

我会在数据库层中执行此操作:

SELECT Distinct...
FROM MyTable

或者如果您需要聚合:

SELECT SUM(Field1), ID FROM MyTable
GROUP BY ID

将SELECT语句放在存储过程中。然后在.net中建立与数据库的连接,调用存储过程,执行.ExecuteNonQuery()。返回数据表中的行并将数据表返回给UI。