如何对 DataTable 执行 SELECT DISTINCT


在 ADO.NET 1.x & 2.0 中, System.Data.DataTable 类虽然公开 Select 方法,但不支持 DISTINCT 关键字,而我们在实际开发中免不了有这样的需求:对已有 DataTable 进行 SELECT  DISTINCT ,返回指定列具有唯一值的行,这些行存在新的 DataTable 中。

对于此问题,很早就有人提出来了,大家也做了很多尝试。

看到 CSDN 中常有人有此疑问,这里再次总结下,便于参阅。

ADO.NET 1.x
对于此版本,没有任何捷径,只有自己手工实现,这里收集两个比较常用的方法:

Select DISTINCT on DataTable
http://weblogs.asp.net/eporter/archive/2005/02/10/370548.aspx

HOWTO: VisualC # .NET 中实现 DataSet SELECTDISTINCT Helper 类
http://support.microsoft.com/kb/326176/zh-cn

推荐方法1,此实现更具性能比。


ADO.NET 2.0


对于此版本,  虽然 DataTable.Select 方法依然不支持 DISTINCT ,但是与 DataTable 密切相关的 DataView 类实现了几个重载版本的 ToDataTable  方法,根据现有 DataView 中的行,创建并返回一个新的 DataTable。
其中
public DataTable ToTable (
 bool distinct,
 params string[] columnNames
)





public DataTable ToTable (
 string tableName,
 bool distinct,
 params string[] columnNames
)
支持 distinct 指示是否对 columnNames 内所有列进行 DISTINCT 操作。







None.gif private   static   void  DemonstrateDataView()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// Create a DataTable with three columns.
InBlock.gif
    DataTable table = new DataTable("NewTable");
InBlock.gif    Console.WriteLine(
"Original table name: " + table.TableName);
InBlock.gif    DataColumn column 
= new DataColumn("ID"typeof(System.Int32));
InBlock.gif    table.Columns.Add(column);
InBlock.gif
InBlock.gif    column 
= new DataColumn("Category"typeof(System.String));
InBlock.gif    table.Columns.Add(column);
InBlock.gif
InBlock.gif    column 
= new DataColumn("Product"typeof(System.String));
InBlock.gif    table.Columns.Add(column);
InBlock.gif
InBlock.gif    column 
= new DataColumn("QuantityInStock"typeof(System.Int32));
InBlock.gif    table.Columns.Add(column);
InBlock.gif
InBlock.gif    
// Add some items.
InBlock.gif
    DataRow row = table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif1"Fruit""Apple"14 };
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    row 
= table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif2"Fruit""Orange"27 };
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    row 
= table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif3"Bread""Muffin"23 };
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    row 
= table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif4"Fish""Salmon"12 };
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    row 
= table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif5"Fish""Salmon"15 };
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    row 
= table.NewRow();
ExpandedSubBlockStart.gifContractedSubBlock.gif    row.ItemArray 
= new object[] dot.gif6"Bread""Croissant"23};
InBlock.gif    table.Rows.Add(row);
InBlock.gif
InBlock.gif    
// Mark all rows as "accepted". Not required
InBlock.gif    
// for this particular example.
InBlock.gif
    table.AcceptChanges();
InBlock.gif
InBlock.gif    
// Print current table values.
InBlock.gif
    PrintTableOrView(table, "Current Values in Table");
InBlock.gif
InBlock.gif    DataView view 
= new DataView(table);
InBlock.gif    view.Sort 
= "Category";
InBlock.gif    PrintTableOrView(view, 
"Current Values in View");
InBlock.gif
InBlock.gif    DataTable newTable 
= view.ToTable("UniqueData"true
InBlock.gif        
"Category""QuantityInStock");
InBlock.gif    PrintTableOrView(newTable, 
"Table created from sorted DataView");
InBlock.gif    Console.WriteLine(
"New table name: " + newTable.TableName);
InBlock.gif
InBlock.gif    Console.WriteLine(
"Press any key to continue.");
InBlock.gif    Console.ReadKey();
ExpandedBlockEnd.gif}

None.gif
None.gif
private   static   void  PrintTableOrView(DataView dv,  string  label)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    System.IO.StringWriter sw;
InBlock.gif    
string output;
InBlock.gif    DataTable table 
= dv.Table;
InBlock.gif
InBlock.gif    Console.WriteLine(label);
InBlock.gif
InBlock.gif    
// Loop through each row in the view.
InBlock.gif
    foreach (DataRowView rowView in dv)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        sw 
= new System.IO.StringWriter();
InBlock.gif
InBlock.gif        
// Loop through each column.
InBlock.gif
        foreach (DataColumn col in table.Columns)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Output the value of each column's data.
InBlock.gif
            sw.Write(rowView[col.ColumnName].ToString() + "");
ExpandedSubBlockEnd.gif        }

InBlock.gif        output 
= sw.ToString();
InBlock.gif        
// Trim off the trailing ", ", so the output looks correct.
InBlock.gif
        if (output.Length > 2)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            output 
= output.Substring(0, output.Length - 2);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
// Display the row in the console window.
InBlock.gif
        Console.WriteLine(output);
ExpandedSubBlockEnd.gif    }

InBlock.gif    Console.WriteLine();
ExpandedBlockEnd.gif}

None.gif
None.gif
private   static   void  PrintTableOrView(DataTable table,  string  label)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    System.IO.StringWriter sw;
InBlock.gif    
string output;
InBlock.gif
InBlock.gif    Console.WriteLine(label);
InBlock.gif
InBlock.gif    
// Loop through each row in the table.
InBlock.gif
    foreach (DataRow row in table.Rows)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        sw 
= new System.IO.StringWriter();
InBlock.gif        
// Loop through each column.
InBlock.gif
        foreach (DataColumn col in table.Columns)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Output the value of each column's data.
InBlock.gif
            sw.Write(row[col].ToString() + "");
ExpandedSubBlockEnd.gif        }

InBlock.gif        output 
= sw.ToString();
InBlock.gif        
// Trim off the trailing ", ", so the output looks correct.
InBlock.gif
        if (output.Length > 2)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            output 
= output.Substring(0, output.Length - 2);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
// Display the row in the console window.
InBlock.gif
        Console.WriteLine(output);
ExpandedSubBlockEnd.gif    }
 //
InBlock.gif
    Console.WriteLine();
ExpandedBlockEnd.gif}


















转载于:https://www.cnblogs.com/Jinglecat/archive/2007/07/16/820339.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值