转自风满袖的Blog http://jiezhi.cnblogs.com/archive/2005/01/05/86838.html
2 using System.Collections;
3 using System.Data;
4
5 namespace Common
6 {
7 /**//**//**//// <summary>
8 /// DataSet助手
9 /// </summary>
10 public class DataSetHelper
11 {
12 private class FieldInfo
13 {
14 public string RelationName;
15 public string FieldName;
16 public string FieldAlias;
17 public string Aggregate;
18 }
19
20 private DataSet ds;
21 private ArrayList m_FieldInfo;
22 private string m_FieldList;
23 private ArrayList GroupByFieldInfo;
24 private string GroupByFieldList;
25
26 public DataSet DataSet
27 {
28 get { return ds; }
29 }
30
31 构造方法#region 构造方法
32
33 public DataSetHelper()
34 {
35 ds = null;
36 }
37
38 public DataSetHelper(ref DataSet dataSet)
39 {
40 ds = dataSet;
41 }
42
43 #endregion
44
45 私有方法#region 私有方法
46
47 /**//// <summary>
48 /// 比较两列
49 /// </summary>
50 /// <param name="objectA"></param>
51 /// <param name="objectB"></param>
52 /// <returns></returns>
53 private bool ColumnEqual(object objectA, object objectB)
54 {
55 if ( objectA == DBNull.Value && objectB == DBNull.Value )
56 {
57 return true;
58 }
59 if ( objectA == DBNull.Value || objectB == DBNull.Value )
60 {
61 return false;
62 }
63 return ( objectA.Equals( objectB ) );
64 }
65
66 /**//// <summary>
67 /// 比较两行
68 /// </summary>
69 /// <param name="rowA">A表的行</param>
70 /// <param name="rowB">B表的行</param>
71 /// <param name="columns">所对应的列</param>
72 /// <returns></returns>
73 private bool RowEqual(DataRow rowA, DataRow rowB, DataColumnCollection columns)
74 {
75 bool result = true;
76 for ( int i = 0; i < columns.Count; i++ )
77 {
78 result &= ColumnEqual( rowA[ columns[ i ].ColumnName ], rowB[ columns[ i ].ColumnName ] );
79 }
80 return result;
81 }
82
83 /**//// <summary>
84 /// 暂时不知道
85 /// </summary>
86 /// <param name="fieldList"></param>
87 /// <param name="allowRelation"></param>
88 private void ParseFieldList(string fieldList, bool allowRelation)
89 {
90 if ( m_FieldList == fieldList )
91 {
92 return;
93 }
94 m_FieldInfo = new ArrayList();
95 m_FieldList = fieldList;
96 FieldInfo Field;
97 string[] FieldParts;
98 string[] Fields = fieldList.Split( ',' );
99 for ( int i = 0; i <= Fields.Length - 1; i++ )
100 {
101 Field = new FieldInfo();
102 FieldParts = Fields[ i ].Trim().Split( ' ' );
103 switch ( FieldParts.Length )
104 {
105 case 1:
106 //to be set at the end of the loop
107 break;
108 case 2:
109 Field.FieldAlias = FieldParts[ 1 ];
110 break;
111 default:
112 return;
113 }
114 FieldParts = FieldParts[ 0 ].Split( '.' );
115 switch ( FieldParts.Length )
116 {
117 case 1:
118 Field.FieldName = FieldParts[ 0 ];
119 break;
120 case 2:
121 if ( allowRelation == false )
122 {
123 return;
124 }
125 Field.RelationName = FieldParts[ 0 ].Trim();
126 Field.FieldName = FieldParts[ 1 ].Trim();
127 break;
128 default:
129 return;
130 }
131 if ( Field.FieldAlias == null )
132 {
133 Field.FieldAlias = Field.FieldName;
134 }
135 m_FieldInfo.Add( Field );
136 }
137 }
138
139 /**//// <summary>
140 /// 创建DataTable
141 /// </summary>
142 /// <param name="tableName">表名</param>
143 /// <param name="sourceTable">源表</param>
144 /// <param name="fieldList"></param>
145 /// <returns></returns>
146 private DataTable CreateTable(string tableName, DataTable sourceTable, string fieldList)
147 {
148 DataTable dt;
149 if ( fieldList.Trim() == "" )
150 {
151 dt = sourceTable.Clone();
152 dt.TableName = tableName;
153 }
154 else
155 {
156 dt = new DataTable( tableName );
157 ParseFieldList( fieldList, false );
158 DataColumn dc;
159 foreach ( FieldInfo Field in m_FieldInfo )
160 {
161 dc = sourceTable.Columns[ Field.FieldName ];
162 DataColumn column = new DataColumn();
163 column.ColumnName = Field.FieldAlias;
164 column.DataType = dc.DataType;
165 column.MaxLength = dc.MaxLength;
166 column.Expression = dc.Expression;
167 dt.Columns.Add( column );
168 }
169 }
170 if ( ds != null )
171 {
172 ds.Tables.Add( dt );
173 }
174 return dt;
175 }
176
177 /**//// <summary>
178 /// 插入表
179 /// </summary>
180 /// <param name="destTable">DataTable</param>
181 /// <param name="sourceTable">源DataTable</param>
182 /// <param name="fieldList"></param>
183 /// <param name="rowFilter"></param>
184 /// <param name="sort"></param>
185 private void InsertInto(DataTable destTable, DataTable sourceTable,
186 string fieldList, string rowFilter, string sort)
187 {
188 ParseFieldList( fieldList, false );
189 DataRow[] rows = sourceTable.Select( rowFilter, sort );
190 DataRow destRow;
191 foreach ( DataRow sourceRow in rows )
192 {
193 destRow = destTable.NewRow();
194 if ( fieldList == "" )
195 {
196 foreach ( DataColumn dc in destRow.Table.Columns )
197 {
198 if ( dc.Expression == "" )
199 {
200 destRow[ dc ] = sourceRow[ dc.ColumnName ];
201 }
202 }
203 }
204 else
205 {
206 foreach ( FieldInfo field in m_FieldInfo )
207 {
208 destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
209 }
210 }
211 destTable.Rows.Add( destRow );
212 }
213 }
214
215 /**//// <summary>
216 /// 暂时不知道
217 /// </summary>
218 /// <param name="FieldList"></param>
219 private void ParseGroupByFieldList(string FieldList)
220 {
221 if ( GroupByFieldList == FieldList )
222 {
223 return;
224 }
225 GroupByFieldInfo = new ArrayList();
226 FieldInfo Field;
227 string[] FieldParts;
228 string[] Fields = FieldList.Split( ',' );
229 for ( int i = 0; i <= Fields.Length - 1; i++ )
230 {
231 Field = new FieldInfo();
232 FieldParts = Fields[ i ].Trim().Split( ' ' );
233 switch ( FieldParts.Length )
234 {
235 case 1:
236 //to be set at the end of the loop
237 break;
238 case 2:
239 Field.FieldAlias = FieldParts[ 1 ];
240 break;
241 default:
242 return;
243 }
244
245 FieldParts = FieldParts[ 0 ].Split( '(' );
246 switch ( FieldParts.Length )
247 {
248 case 1:
249 Field.FieldName = FieldParts[ 0 ];
250 break;
251 case 2:
252 Field.Aggregate = FieldParts[ 0 ].Trim().ToLower();
253 Field.FieldName = FieldParts[ 1 ].Trim( ' ', ')' );
254 break;
255 default:
256 return;
257 }
258 if ( Field.FieldAlias == null )
259 {
260 if ( Field.Aggregate == null )
261 {
262 Field.FieldAlias = Field.FieldName;
263 }
264 else
265 {
266 Field.FieldAlias = Field.Aggregate + "of" + Field.FieldName;
267 }
268 }
269 GroupByFieldInfo.Add( Field );
270 }
271 GroupByFieldList = FieldList;
272 }
273
274 /**//// <summary>
275 /// 创建一个分组DataTable
276 /// </summary>
277 /// <param name="tableName">表名</param>
278 /// <param name="sourceTable">DataTable</param>
279 /// <param name="fieldList">分组字段</param>
280 /// <returns></returns>
281 private DataTable CreateGroupByTable(string tableName, DataTable sourceTable, string fieldList)
282 {
283 if ( fieldList == null || fieldList.Length == 0 )
284 {
285 return sourceTable.Clone();
286 }
287 else
288 {
289 DataTable dt = new DataTable( tableName );
290 ParseGroupByFieldList( fieldList );
291 foreach ( FieldInfo Field in GroupByFieldInfo )
292 {
293 DataColumn dc = sourceTable.Columns[ Field.FieldName ];
294 if ( Field.Aggregate == null )
295 {
296 dt.Columns.Add( Field.FieldAlias, dc.DataType, dc.Expression );
297 }
298 else
299 {
300 dt.Columns.Add( Field.FieldAlias, dc.DataType );
301 }
302 }
303 if ( ds != null )
304 {
305 ds.Tables.Add( dt );
306 }
307 return dt;
308 }
309 }
310
311 private void InsertGroupByInto(DataTable destTable, DataTable sourceTable, string fieldList,
312 string rowFilter, string groupBy)
313 {
314 if ( fieldList == null || fieldList.Length == 0 )
315 {
316 return;
317 }
318 ParseGroupByFieldList( fieldList );
319 ParseFieldList( groupBy, false );
320 DataRow[] rows = sourceTable.Select( rowFilter, groupBy );
321 DataRow lastSourceRow = null, destRow = null;
322 bool sameRow;
323 int rowCount = 0;
324 foreach ( DataRow sourceRow in rows )
325 {
326 sameRow = false;
327 if ( lastSourceRow != null )
328 {
329 sameRow = true;
330 foreach ( FieldInfo Field in m_FieldInfo )
331 {
332 if ( !ColumnEqual( lastSourceRow[ Field.FieldName ], sourceRow[ Field.FieldName ] ) )
333 {
334 sameRow = false;
335 break;
336 }
337 }
338 if ( !sameRow )
339 {
340 destTable.Rows.Add( destRow );
341 }
342 }
343 if ( !sameRow )
344 {
345 destRow = destTable.NewRow();
346 rowCount = 0;
347 }
348 rowCount += 1;
349 foreach ( FieldInfo field in GroupByFieldInfo )
350 {
351 switch ( field.Aggregate.ToLower() )
352 {
353 case null:
354 case "":
355 case "last":
356 destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
357 break;
358 case "first":
359 if ( rowCount == 1 )
360 {
361 destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
362 }
363 break;
364 case "count":
365 destRow[ field.FieldAlias ] = rowCount;
366 break;
367 case "sum":
368 destRow[ field.FieldAlias ] = Add( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
369 break;
370 case "max":
371 destRow[ field.FieldAlias ] = Max( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
372 break;
373 case "min":
374 if ( rowCount == 1 )
375 {
376 destRow[ field.FieldAlias ] = sourceRow[ field.FieldName ];
377 }
378 else
379 {
380 destRow[ field.FieldAlias ] = Min( destRow[ field.FieldAlias ], sourceRow[ field.FieldName ] );
381 }
382 break;
383 }
384 }
385 lastSourceRow = sourceRow;
386 }
387 if ( destRow != null )
388 {
389 destTable.Rows.Add( destRow );
390 }
391 }
392
393 private object Min(object a, object b)
394 {
395 if ( ( a is DBNull ) || ( b is DBNull ) )
396 {
397 return DBNull.Value;
398 }
399 if ( ( (IComparable) a ).CompareTo( b ) == -1 )
400 {
401 return a;
402 }
403 else
404 {
405 return b;
406 }
407 }
408
409 private object Max(object a, object b)
410 {
411 if ( a is DBNull )
412 {
413 return b;
414 }
415 if ( b is DBNull )
416 {
417 return a;
418 }
419 if ( ( (IComparable) a ).CompareTo( b ) == 1 )
420 {
421 return a;
422 }
423 else
424 {
425 return b;
426 }
427 }
428
429 private object Add(object a, object b)
430 {
431 if ( a is DBNull )
432 {
433 return b;
434 }
435 if ( b is DBNull )
436 {
437 return a;
438 }
439 return ( (decimal) a + (decimal) b );
440 }
441
442 private DataTable CreateJoinTable(string tableName, DataTable sourceTable, string fieldList)
443 {
444 if ( fieldList == null )
445 {
446 return sourceTable.Clone();
447 }
448 else
449 {
450 DataTable dt = new DataTable( tableName );
451 ParseFieldList( fieldList, true );
452 foreach ( FieldInfo field in m_FieldInfo )
453 {
454 if ( field.RelationName == null )
455 {
456 DataColumn dc = sourceTable.Columns[ field.FieldName ];
457 dt.Columns.Add( dc.ColumnName, dc.DataType, dc.Expression );
458 }
459 else
460 {
461 DataColumn dc = sourceTable.ParentRelations[ field.RelationName ].ParentTable.Columns[ field.FieldName ];
462 dt.Columns.Add( dc.ColumnName, dc.DataType, dc.Expression );
463 }
464 }
465 if ( ds != null )
466 {
467 ds.Tables.Add( dt );
468 }
469 return dt;
470 }
471 }
472
473 private void InsertJoinInto(DataTable destTable, DataTable sourceTable,
474 string fieldList, string rowFilter, string sort)
475 {
476 if ( fieldList == null )
477 {
478 return;
479 }
480 else
481 {
482 ParseFieldList( fieldList, true );
483 DataRow[] Rows = sourceTable.Select( rowFilter, sort );
484 foreach ( DataRow SourceRow in Rows )
485 {
486 DataRow DestRow = destTable.NewRow();
487 foreach ( FieldInfo Field in m_FieldInfo )
488 {
489 if ( Field.RelationName == null )
490 {
491 DestRow[ Field.FieldName ] = SourceRow[ Field.FieldName ];
492 }
493 else
494 {
495 DataRow ParentRow = SourceRow.GetParentRow( Field.RelationName );
496 DestRow[ Field.FieldName ] = ParentRow[ Field.FieldName ];
497 }
498 }
499 destTable.Rows.Add( DestRow );
500 }
501 }
502 }
503
504 #endregion
505
506 SelectDistinct / Distinct#region SelectDistinct / Distinct
507
508 /**//**//**//// <summary>
509 /// 按照fieldName从sourceTable中选择出不重复的行,
510 /// 相当于select distinct fieldName from sourceTable
511 /// </summary>
512 /// <param name="tableName">表名</param>
513 /// <param name="sourceTable">源DataTable</param>
514 /// <param name="fieldName">列名</param>
515 /// <returns>一个新的不含重复行的DataTable,列只包括fieldName指明的列</returns>
516 public DataTable SelectDistinct(string tableName, DataTable sourceTable, string fieldName)
517 {
518 DataTable dt = new DataTable( tableName );
519 dt.Columns.Add( fieldName, sourceTable.Columns[ fieldName ].DataType );
520
521 object lastValue = null;
522 foreach ( DataRow dr in sourceTable.Select( "", fieldName ) )
523 {
524 if ( lastValue == null || !( ColumnEqual( lastValue, dr[ fieldName ] ) ) )
525 {
526 lastValue = dr[ fieldName ];
527 dt.Rows.Add( new object[]{lastValue} );
528 }
529 }
530 if ( ds != null && !ds.Tables.Contains( tableName ) )
531 {
532 ds.Tables.Add( dt );
533 }
534 return dt;
535 }
536
537 /**//**//**//// <summary>
538 /// 按照fieldName从sourceTable中选择出不重复的行,
539 /// 相当于select distinct fieldName1,fieldName2,,fieldNamen from sourceTable
540 /// </summary>
541 /// <param name="tableName">表名</param>
542 /// <param name="sourceTable">源DataTable</param>
543 /// <param name="fieldNames">列名数组</param>
544 /// <returns>一个新的不含重复行的DataTable,列只包括fieldNames中指明的列</returns>
545 public DataTable SelectDistinct(string tableName, DataTable sourceTable, string[] fieldNames)
546 {
547 DataTable dt = new DataTable( tableName );
548 object[] values = new object[fieldNames.Length];
549 string fields = "";
550 for ( int i = 0; i < fieldNames.Length; i++ )
551 {
552 dt.Columns.Add( fieldNames[ i ], sourceTable.Columns[ fieldNames[ i ] ].DataType );
553 fields += fieldNames[ i ] + ",";
554 }
555 fields = fields.Remove( fields.Length - 1, 1 );
556 DataRow lastRow = null;
557 foreach ( DataRow dr in sourceTable.Select( "", fields ) )
558 {
559 if ( lastRow == null || !( RowEqual( lastRow, dr, dt.Columns ) ) )
560 {
561 lastRow = dr;
562 for ( int i = 0; i < fieldNames.Length; i++ )
563 {
564 values[ i ] = dr[ fieldNames[ i ] ];
565 }
566 dt.Rows.Add( values );
567 }
568 }
569 if ( ds != null && !ds.Tables.Contains( tableName ) )
570 {
571 ds.Tables.Add( dt );
572 }
573 return dt;
574 }
575
576 /**//**//**//// <summary>
577 /// 按照fieldName从sourceTable中选择出不重复的行,
578 /// 并且包含sourceTable中所有的列。
579 /// </summary>
580 /// <param name="tableName">表名</param>
581 /// <param name="sourceTable">源表</param>
582 /// <param name="fieldName">字段</param>
583 /// <returns>一个新的不含重复行的DataTable</returns>
584 public DataTable Distinct(string tableName, DataTable sourceTable, string fieldName)
585 {
586 DataTable dt = sourceTable.Clone();
587 dt.TableName = tableName;
588
589 object lastValue = null;
590 foreach ( DataRow dr in sourceTable.Select( "", fieldName ) )
591 {
592 if ( lastValue == null || !( ColumnEqual( lastValue, dr[ fieldName ] ) ) )
593 {
594 lastValue = dr[ fieldName ];
595 dt.Rows.Add( dr.ItemArray );
596 }
597 }
598 if ( ds != null && !ds.Tables.Contains( tableName ) )
599 {
600 ds.Tables.Add( dt );
601 }
602 return dt;
603 }
604
605 /**//**//**//// <summary>
606 /// 按照fieldNames从sourceTable中选择出不重复的行,
607 /// 并且包含sourceTable中所有的列。
608 /// </summary>
609 /// <param name="tableName">表名</param>
610 /// <param name="sourceTable">源表</param>
611 /// <param name="fieldNames">字段</param>
612 /// <returns>一个新的不含重复行的DataTable</returns>
613 public DataTable Distinct(string tableName, DataTable sourceTable, string[] fieldNames)
614 {
615 DataTable dt = sourceTable.Clone();
616 dt.TableName = tableName;
617 string fields = "";
618 for ( int i = 0; i < fieldNames.Length; i++ )
619 {
620 fields += fieldNames[ i ] + ",";
621 }
622 fields = fields.Remove( fields.Length - 1, 1 );
623 DataRow lastRow = null;
624 foreach ( DataRow dr in sourceTable.Select( "", fields ) )
625 {
626 if ( lastRow == null || !( RowEqual( lastRow, dr, dt.Columns ) ) )
627 {
628 lastRow = dr;
629 dt.Rows.Add( dr.ItemArray );
630 }
631 }
632 if ( ds != null && !ds.Tables.Contains( tableName ) )
633 {
634 ds.Tables.Add( dt );
635 }
636 return dt;
637 }
638
639 #endregion
640
641 Select Table Into#region Select Table Into
642
643 /**//**//**//// <summary>
644 /// 按sort排序,按rowFilter过滤sourceTable,
645 /// 复制fieldList中指明的字段的数据到新DataTable,并返回之
646 /// </summary>
647 /// <param name="tableName">表名</param>
648 /// <param name="sourceTable">源表</param>
649 /// <param name="fieldList">字段列表</param>
650 /// <param name="rowFilter">过滤条件</param>
651 /// <param name="sort">排序</param>
652 /// <returns>新DataTable</returns>
653 public DataTable SelectInto(string tableName, DataTable sourceTable,
654 string fieldList, string rowFilter, string sort)
655 {
656 DataTable dt = CreateTable( tableName, sourceTable, fieldList );
657 InsertInto( dt, sourceTable, fieldList, rowFilter, sort );
658 return dt;
659 }
660
661 #endregion
662
663 Group By Table#region Group By Table
664
665 public DataTable SelectGroupByInto(string tableName, DataTable sourceTable, string fieldList,
666 string rowFilter, string groupBy)
667 {
668 DataTable dt = CreateGroupByTable( tableName, sourceTable, fieldList );
669 InsertGroupByInto( dt, sourceTable, fieldList, rowFilter, groupBy );
670 return dt;
671 }
672
673 #endregion
674
675 Join Tables#region Join Tables
676
677 public DataTable SelectJoinInto(string tableName, DataTable sourceTable, string fieldList, string rowFilter, string sort)
678 {
679 DataTable dt = CreateJoinTable( tableName, sourceTable, fieldList );
680 InsertJoinInto( dt, sourceTable, fieldList, rowFilter, sort );
681 return dt;
682 }
683
684 #endregion
685
686 Create Table#region Create Table
687
688 public DataTable CreateTable(string tableName, string fieldList)
689 {
690 DataTable dt = new DataTable( tableName );
691 DataColumn dc;
692 string[] Fields = fieldList.Split( ',' );
693 string[] FieldsParts;
694 string Expression;
695 foreach ( string Field in Fields )
696 {
697 FieldsParts = Field.Trim().Split( " ".ToCharArray(), 3 ); // allow for spaces in the expression
698 // add fieldname and datatype
699 if ( FieldsParts.Length == 2 )
700 {
701 dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ) );
702 dc.AllowDBNull = true;
703 }
704 else if ( FieldsParts.Length == 3 ) // add fieldname, datatype, and expression
705 {
706 Expression = FieldsParts[ 2 ].Trim();
707 if ( Expression.ToUpper() == "REQUIRED" )
708 {
709 dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ) );
710 dc.AllowDBNull = false;
711 }
712 else
713 {
714 dc = dt.Columns.Add( FieldsParts[ 0 ].Trim(), Type.GetType( "System." + FieldsParts[ 1 ].Trim(), true, true ), Expression );
715 }
716 }
717 else
718 {
719 return null;
720 }
721 }
722 if ( ds != null )
723 {
724 ds.Tables.Add( dt );
725 }
726 return dt;
727 }
728
729 public DataTable CreateTable(string tableName, string fieldList, string keyFieldList)
730 {
731 DataTable dt = CreateTable( tableName, fieldList );
732 string[] KeyFields = keyFieldList.Split( ',' );
733 if ( KeyFields.Length > 0 )
734 {
735 DataColumn[] KeyFieldColumns = new DataColumn[KeyFields.Length];
736 int i;
737 for ( i = 1; i == KeyFields.Length - 1; ++i )
738 {
739 KeyFieldColumns[ i ] = dt.Columns[ KeyFields[ i ].Trim() ];
740 }
741 dt.PrimaryKey = KeyFieldColumns;
742 }
743 return dt;
744 }
745
746 #endregion
747 }
748}
749
2.
关于DataSetHelper类(从微软MSDN整理出来)
public class DataSetHelper
{
public DataSet ds;
private System.Collections.ArrayList m_FieldInfo;
private string m_FieldList;
private System.Collections.ArrayList GroupByFieldInfo;
private string GroupByFieldList;
public DataSetHelper(ref DataSet DataSet)
{
ds = DataSet;
}
public DataSetHelper()
{
ds = null;
}
private class FieldInfo
{
public string RelationName;
public string FieldName; //source table field name
public string FieldAlias; //destination table field name
public string Aggregate;
}
private bool ColumnEqual(object a, object b)
{
// Compares two values to see if they are equal. Also compares DBNULL.Value.
// Note: If your DataTable contains object fields, then you must extend this
// function to handle them in a meaningful way if you intend to group on them.
if ( a == DBNull.Value && b == DBNull.Value ) // both are DBNull.Value
return true;
if ( a == DBNull.Value || b == DBNull.Value ) // only one is DBNull.Value
return false;
return ( a.Equals(b) ); // value type standard comparison
}
/// <summary>
/// 不重复记录的DataTable
/// </summary>
/// <param name="TableName">新表名</param>
/// <param name="SourceTable">源数据表</param>
/// <param name="FieldName">消除不重复的字段</param>
/// <returns>DataTable</returns>
public DataTable SelectDistinct(string TableName, DataTable SourceTable, string FieldName)
{
DataTable dt = new DataTable(TableName);
dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);
object LastValue = null;
foreach (DataRow dr in SourceTable.Select("", FieldName))
{
if ( LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])) )
{
LastValue = dr[FieldName];
dt.Rows.Add(new object[]{LastValue});
}
}
if (ds != null)
ds.Tables.Add(dt);
return dt;
}
public DataTable SelectDistinct( DataTable SourceTable, string FieldName)
{
return SelectDistinct( "table1", SourceTable, FieldName );
}
private void ParseFieldList(string FieldList, bool AllowRelation)
{
/*
* This code parses FieldList into FieldInfo objects and then
* adds them to the m_FieldInfo private member
*
* FieldList systax: [relationname.]fieldname[ alias], ...
*/
if (m_FieldList == FieldList) return;
m_FieldInfo = new System.Collections.ArrayList();
m_FieldList = FieldList;
FieldInfo Field; string[] FieldParts; string[] Fields=FieldList.Split(',');
int i;
for (i=0; i<=Fields.Length-1; i++)
{
Field=new FieldInfo();
//parse FieldAlias
FieldParts = Fields[i].Trim().Split(' ');
switch (FieldParts.Length)
{
case 1:
//to be set at the end of the loop
break;
case 2:
Field.FieldAlias=FieldParts[1];
break;
default:
throw new Exception("Too many spaces in field definition: '" + Fields[i] + "'.");
}
//parse FieldName and RelationName
FieldParts = FieldParts[0].Split('.');
switch (FieldParts.Length)
{
case 1:
Field.FieldName=FieldParts[0];
break;
case 2:
if (AllowRelation==false)
throw new Exception("Relation specifiers not permitted in field list: '" + Fields[i] + "'.");
Field.RelationName = FieldParts[0].Trim();
Field.FieldName=FieldParts[1].Trim();
break;
default:
throw new Exception("Invalid field definition: " + Fields[i] + "'.");
}
if (Field.FieldAlias==null)
Field.FieldAlias = Field.FieldName;
m_FieldInfo.Add (Field);
}
}
private void ParseGroupByFieldList(string FieldList)
{
/*
* Parses FieldList into FieldInfo objects and adds them to the GroupByFieldInfo private member
*
* FieldList syntax: fieldname[ alias]|operatorname(fieldname)[ alias],...
*
* Supported Operators: count,sum,max,min,first,last
*/
if (GroupByFieldList == FieldList) return;
GroupByFieldInfo = new System.Collections.ArrayList();
FieldInfo Field; string[] FieldParts; string[] Fields = FieldList.Split(',');
for (int i=0; i<=Fields.Length-1;i++)
{
Field = new FieldInfo();
//Parse FieldAlias
FieldParts = Fields[i].Trim().Split(' ');
switch (FieldParts.Length)
{
case 1:
//to be set at the end of the loop
break;
case 2:
Field.FieldAlias = FieldParts[1];
break;
default:
throw new ArgumentException("Too many spaces in field definition: '" + Fields[i] + "'.");
}
//Parse FieldName and Aggregate
FieldParts = FieldParts[0].Split('(');
switch (FieldParts.Length)
{
case 1:
Field.FieldName = FieldParts[0];
break;
case 2:
Field.Aggregate = FieldParts[0].Trim().ToLower(); //we're doing a case-sensitive comparison later
Field.FieldName = FieldParts[1].Trim(' ', ')');
break;
default:
throw new ArgumentException("Invalid field definition: '" + Fields[i] + "'.");
}
if (Field.FieldAlias==null)
{
if (Field.Aggregate==null)
Field.FieldAlias=Field.FieldName;
else
Field.FieldAlias = Field.Aggregate + "of" + Field.FieldName;
}
GroupByFieldInfo.Add(Field);
}
GroupByFieldList = FieldList;
}
public DataTable CreateGroupByTable(string TableName, DataTable SourceTable, string FieldList)
{
/*
* Creates a table based on aggregates of fields of another table
*
* RowFilter affects rows before GroupBy operation. No "Having" support
* though this can be emulated by subsequent filtering of the table that results
*
* FieldList syntax: fieldname[ alias]|aggregatefunction(fieldname)[ alias], ...
*/
if (FieldList == null)
{
throw new ArgumentException("You must specify at least one field in the field list.");
//return CreateTable(TableName, SourceTable);
}
else
{
DataTable dt = new DataTable(TableName);
ParseGroupByFieldList(FieldList);
foreach (FieldInfo Field in GroupByFieldInfo)
{
DataColumn dc = SourceTable.Columns[Field.FieldName];
if (Field.Aggregate==null)
dt.Columns.Add(Field.FieldAlias, dc.DataType, dc.Expression);
else
dt.Columns.Add(Field.FieldAlias, dc.DataType);
}
if (ds != null)
ds.Tables.Add(dt);
return dt;
}
}
public void InsertGroupByInto(DataTable DestTable, DataTable SourceTable, string FieldList,
string RowFilter, string GroupBy)
{
/*
* Copies the selected rows and columns from SourceTable and inserts them into DestTable
* FieldList has same format as CreateGroupByTable
*/
if (FieldList == null)
throw new ArgumentException("You must specify at least one field in the field list.");
ParseGroupByFieldList(FieldList); //parse field list
ParseFieldList(GroupBy,false); //parse field names to Group By into an arraylist
DataRow[] Rows = SourceTable.Select(RowFilter, GroupBy);
DataRow LastSourceRow = null, DestRow = null; bool SameRow; int RowCount=0;
foreach(DataRow SourceRow in Rows)
{
SameRow=false;
if (LastSourceRow!=null)
{
SameRow=true;
foreach(FieldInfo Field in m_FieldInfo)
{
if (!ColumnEqual(LastSourceRow[Field.FieldName], SourceRow[Field.FieldName]))
{
SameRow=false;
break;
}
}
if (!SameRow)
DestTable.Rows.Add(DestRow);
}
if (!SameRow)
{
DestRow = DestTable.NewRow();
RowCount=0;
}
RowCount+=1;
foreach(FieldInfo Field in GroupByFieldInfo)
{
switch(Field.Aggregate) //this test is case-sensitive
{
case null: //implicit last
case "": //implicit last
case "last":
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
break;
case "first":
if (RowCount==1)
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
break;
case "count":
DestRow[Field.FieldAlias]=RowCount;
break;
case "sum":
DestRow[Field.FieldAlias]=Add(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
case "max":
DestRow[Field.FieldAlias]=Max(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
case "min":
if (RowCount==1)
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
else
DestRow[Field.FieldAlias]=Min(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
}
}
LastSourceRow = SourceRow;
}
if(DestRow!=null)
DestTable.Rows.Add(DestRow);
}
private FieldInfo LocateFieldInfoByName(System.Collections.ArrayList FieldList, string Name)
{
//Looks up a FieldInfo record based on FieldName
foreach (FieldInfo Field in FieldList)
{
if (Field.FieldName==Name)
return Field;
}
return null;
}
private object Min(object a, object b)
{
//Returns MIN of two values - DBNull is less than all others
if ((a is DBNull) || (b is DBNull))
return DBNull.Value;
if (((IComparable)a).CompareTo(b)==-1)
return a;
else
return b;
}
private object Max(object a, object b)
{
//Returns Max of two values - DBNull is less than all others
if (a is DBNull)
return b;
if (b is DBNull)
return a;
if (((IComparable)a).CompareTo(b)==1)
return a;
else
return b;
}
private object Add(object a, object b)
{
//Adds two values - if one is DBNull, then returns the other
if (a is DBNull)
return b;
if (b is DBNull)
return a;
return ((decimal)a + (decimal)b);
}
public DataTable SelectGroupByInto(string TableName, DataTable SourceTable, string FieldList,
string RowFilter, string GroupBy)
{
/*
* Selects data from one DataTable to another and performs various aggregate functions
* along the way. See InsertGroupByInto and ParseGroupByFieldList for supported aggregate functions.
*/
DataTable dt = CreateGroupByTable(TableName, SourceTable, FieldList);
InsertGroupByInto(dt, SourceTable, FieldList, RowFilter, GroupBy);
return dt;
}
}
3.
1建立一个DataSetHelper类(DataSetHelper.cs)
public class DataSetHelper
{
public DataSet ds;
public DataSetHelper(ref DataSet DataSet)
{
ds = DataSet;
}
public DataSetHelper()
{
ds = null;
}
private bool ColumnEqual(object A, object B)
{
if (A == DBNull.Value && B == DBNull.Value) // both are DBNull.Value
return true;
if (A == DBNull.Value || B == DBNull.Value) // only one is DBNull.Value
return false;
return (A.Equals(B)); // value type standard comparison
}
public DataTable SelectDistinct(string TableName, DataTable SourceTable, string FieldName)
{
DataTable dt = new DataTable(TableName);
dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);
object LastValue = null;
foreach (DataRow dr in SourceTable.Select("", FieldName))
{
if (LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])))
{
LastValue = dr[FieldName];
dt.Rows.Add(new object[] { LastValue });
}
}
if (ds != null)
ds.Tables.Add(dt);
return dt;
}
}2 建立一个Web窗体,在page_load中写下面的代码 DataSet ds;
DataSetHelper dsHelper;
ds = new DataSet();
dsHelper = new DataSetHelper(ref ds);
// Create source table
DataTable dt = new DataTable("Orders");
dt.Columns.Add("EmployeeID", Type.GetType("System.String"));
dt.Columns.Add("OrderID", Type.GetType("System.Int32"));
dt.Columns.Add("Amount", Type.GetType("System.Decimal"));
dt.Rows.Add(new object[] { "Sam", 5, 25.00 });
dt.Rows.Add(new object[] { "Tom", 7, 50.00 });
dt.Rows.Add(new object[] { "Sue", 9, 11.00 });
dt.Rows.Add(new Object[] { "Tom", 12, 7.00 });
dt.Rows.Add(new Object[] { "Sam", 14, 512.00 });
dt.Rows.Add(new Object[] { "Sue", 15, 17.00 });
dt.Rows.Add(new Object[] { "Sue", 22, 2.50 });
dt.Rows.Add(new object[] { "Tom", 24, 3.00 });
dt.Rows.Add(new object[] { "Tom", 33, 78.75 });
ds.Tables.Add(dt);
DataTable td=dsHelper.SelectDistinct("DistinctEmployees", ds.Tables["Orders"], "EmployeeID");
this.GridView1.DataSource = td;
this.GridView1.DataBind();
该文章转载自网络大本营:http://www.xrss.cn/Info/15184.Html
4.
/** <summary>
/// 返回执行Select distinct后的DataTable
/// </summary>
/// <param name="SourceTable">源数据表</param>
/// <param name="FieldNames">字段集</param>
/// <returns></returns>
private DataTable SelectDistinct(DataTable SourceTable, params string[] FieldNames)
{
object[] lastValues;
DataTable newTable;
DataRow[] orderedRows;
if (FieldNames == null || FieldNames.Length == 0)
throw new ArgumentNullException("FieldNames");
lastValues = new object[FieldNames.Length];
newTable = new DataTable();
foreach (string fieldName in FieldNames)
newTable.Columns.Add(fieldName, SourceTable.Columns[fieldName].DataType);
orderedRows = SourceTable.Select("", string.Join(",", FieldNames));
foreach (DataRow row in orderedRows)
{
if (!fieldValuesAreEqual(lastValues, row, FieldNames))
{
newTable.Rows.Add(createRowClone(row, newTable.NewRow(), FieldNames));
setLastValues(lastValues, row, FieldNames);
}
}
return newTable;
}
private bool fieldValuesAreEqual(object[] lastValues, DataRow currentRow, string[] fieldNames)
{
bool areEqual = true;
for (int i = 0; i < fieldNames.Length; i++)
{
if (lastValues[i] == null || !lastValues[i].Equals(currentRow[fieldNames[i]]))
{
areEqual = false;
break;
}
}
return areEqual;
}
private DataRow createRowClone(DataRow sourceRow, DataRow newRow, string[] fieldNames)
{
foreach (string field in fieldNames)
newRow[field] = sourceRow[field];
return newRow;
}
private void setLastValues(object[] lastValues, DataRow sourceRow, string[] fieldNames)
{
for (int i = 0; i < fieldNames.Length; i++)
lastValues[i] = sourceRow[fieldNames[i]];
}
使用方法
DataTable dt=(System.Data.DataTable)this.ViewState["Mydt"];
string[] fileds={"Filed1","Filed2"};//DISTINCT字段数组
DataTable newdt=this.SelectDistinct(dt,fileds);//返回过滤后的DataTable