转自风满袖的Blog http://jiezhi.cnblogs.com/archive/2005/01/05/86838.html
1using System;
2using System.Collections;
3using System.Data;
4
5namespace 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
2using System.Collections;
3using System.Data;
4
5namespace 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