forked from cyq1162/cyqdata
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMDataTable.cs
1912 lines (1835 loc) · 65.3 KB
/
MDataTable.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Data.Common;
using System.ComponentModel;
using CYQ.Data.UI;
using CYQ.Data.Cache;
using CYQ.Data.SQL;
using CYQ.Data.Tool;
using System.Collections.Specialized;
using System.Web;
namespace CYQ.Data.Table
{
/// <summary>
/// 表格
/// </summary>
public partial class MDataTable
{
private const string DefaultTableName = "SysDefault";
#region 隐式转换
/// <summary>
/// 从DataReader隐式转换成MDataTable
/// </summary>
public static implicit operator MDataTable(DbDataReader sdr)
{
MDataTable dt = CreateFrom(sdr);
if (sdr != null)
{
sdr.Close();
sdr.Dispose();
sdr = null;
}
return dt;
}
/// <summary>
/// 从DataTable隐式转换成MDataTable
/// </summary>
public static implicit operator MDataTable(DataTable dt)
{
if (dt == null)
{
return null;
}
MDataTable mdt = new MDataTable(dt.TableName);
if (dt.Columns != null && dt.Columns.Count > 0)
{
foreach (DataColumn item in dt.Columns)
{
MCellStruct mcs = new MCellStruct(item.ColumnName, DataType.GetSqlType(item.DataType), item.ReadOnly, item.AllowDBNull, item.MaxLength);
mcs.valueType = item.DataType;
mdt.Columns.Add(mcs);
}
foreach (DataRow row in dt.Rows)
{
MDataRow mdr = mdt.NewRow();
for (int i = 0; i < dt.Columns.Count; i++)
{
mdr[i].Value = row[i];
}
mdt.Rows.Add(mdr, row.RowState != DataRowState.Modified);
}
}
return mdt;
}
/// <summary>
/// 从行集合隐式转换成MDataTable
/// </summary>
/// <param name="rows"></param>
/// <returns></returns>
public static implicit operator MDataTable(List<MDataRow> rows)
{
return (MDataRowCollection)rows;
}
/// <summary>
/// 将一行数据装载成一个表。
/// </summary>
/// <returns></returns>
public static implicit operator MDataTable(MDataRow row)
{
MDataTable mTable = new MDataTable(row.TableName);
mTable.Conn = row.Conn;
mTable.LoadRow(row);
return mTable;
}
/// <summary>
/// 将一行数据装载成一个表。
/// </summary>
/// <returns></returns>
public static implicit operator MDataTable(MDataRowCollection rows)
{
if (rows == null || rows.Count == 0)
{
return null;
}
MDataTable mdt = new MDataTable(rows[0].TableName);
mdt.Conn = rows[0].Conn;
mdt.Columns = rows[0].Columns;
mdt.Rows.AddRange(rows);
return mdt;
}
#endregion
#region 属性
private MDataRowCollection _Rows;
/// <summary>
/// 表格行
/// </summary>
public MDataRowCollection Rows
{
get
{
return _Rows;
}
}
[NonSerialized]
private object _DynamicData;
/// <summary>
/// 动态存储数据(如:AcceptChanges 产生的异常默认由本参数存储)
/// </summary>
public object DynamicData
{
get { return _DynamicData; }
set { _DynamicData = value; }
}
public MDataTable()
{
Init(DefaultTableName, null);
}
public MDataTable(string tableName)
{
Init(tableName, null);
}
public MDataTable(string tableName, MDataColumn mdc)
{
Init(tableName, mdc);
}
private void Init(string tableName, MDataColumn mdc)
{
_Rows = new MDataRowCollection(this);
_TableName = tableName;
if (_Columns == null)
{
_Columns = new MDataColumn(this);
if (mdc != null)
{
_Columns.AddRange(mdc);
}
}
}
private string _TableName = string.Empty;
/// <summary>
/// 表名
/// </summary>
public string TableName
{
get
{
if (string.IsNullOrEmpty(_TableName) && Columns != null)
{
_TableName = Columns.TableName;
}
return _TableName;
}
set
{
_TableName = value;
}
}
private string _Description = string.Empty;
/// <summary>
/// 表名描述
/// </summary>
public string Description
{
get
{
if (string.IsNullOrEmpty(_Description) && Columns != null)
{
_Description = Columns.Description;
}
return _Description;
}
set
{
_Description = value;
}
}
private MDataColumn _Columns;
/// <summary>
/// 表格的架构列
/// </summary>
public MDataColumn Columns
{
get
{
return _Columns;
}
set
{
_Columns = value;
_Columns._Table = this;
if (_TableName == DefaultTableName)
{
_TableName = _Columns.TableName;
}
else
{
_Columns.TableName = _TableName;
}
}
}
private string _Conn;
/// <summary>
/// 该表归属的数据库链接。
/// </summary>
public string Conn
{
get
{
if (string.IsNullOrEmpty(_Conn))
{
return AppConfig.DB.DefaultConn;
}
return _Conn;
}
set
{
_Conn = value;
}
}
#endregion
#region 方法
/// <summary>
/// 新建一行
/// </summary>
/// <returns></returns>
public MDataRow NewRow()
{
return NewRow(false);
}
/// <summary>
/// 新建一行
/// </summary>
/// <param name="isAddToTable">是否顺带添加到表中</param>
/// <returns></returns>
public MDataRow NewRow(bool isAddToTable)
{
return NewRow(isAddToTable, -1);
}
/// <summary>
/// 新建一行
/// </summary>
/// <param name="index">插入的索引</param>
/// <returns></returns>
public MDataRow NewRow(bool isAddToTable, int index)
{
MDataRow mdr = new MDataRow(this);
if (isAddToTable)
{
if (index < 0)
{
Rows.Add(mdr, false);
}
else
{
Rows.Insert(index, mdr);
}
}
return mdr;
}
#region 准备新开始的方法
/// <summary>
/// 使用本查询,得到克隆后的数据
/// </summary>
public MDataTable Select(object where)
{
return Select(0, 0, where);
}
/// <summary>
/// 使用本查询,得到克隆后的数据
/// </summary>
public MDataTable Select(int topN, object where)
{
return Select(1, topN, where);
}
/// <summary>
/// 使用本查询,得到克隆后的数据
/// </summary>
public MDataTable Select(int pageIndex, int pageSize, object where, params object[] selectColumns)
{
return MDataTableFilter.Select(this, pageIndex, pageSize, where, selectColumns);
}
/// <summary>
/// 使用本查询,得到原数据的引用。
/// </summary>
public MDataRow FindRow(object where)
{
return MDataTableFilter.FindRow(this, where);
}
/// <summary>
/// 使用本查询,得到原数据的引用。
/// </summary>
public MDataRowCollection FindAll(object where)
{
return MDataTableFilter.FindAll(this, where);
}
/// <summary>
/// 统计满足条件的行所在的索引
/// </summary>
public int GetIndex(object where)
{
return MDataTableFilter.GetIndex(this, where);
}
/// <summary>
/// 统计满足条件的行数
/// </summary>
public int GetCount(object where)
{
return MDataTableFilter.GetCount(this, where);
}
/// <summary>
/// 根据条件分拆成两个表【满足条件,和非满足条件的】,分出来的数据行和原始表仍是同一个引用
/// </summary>
public MDataTable[] Split(object where)
{
return MDataTableFilter.Split(this, where);
}
#endregion
/// <summary>
/// 加载行(包括行架构)[提示,仅当表为空架构时有效]
/// </summary>
/// <param name="row"></param>
internal void LoadRow(MDataRow row) //是否直接能用Row.Table呢??、
{
if (this.Columns.Count == 0 && row != null && row.Count > 0)
{
this.Columns = row.Columns.Clone();
if (!string.IsNullOrEmpty(_TableName) && _TableName.StartsWith("SysDefault"))
{
_TableName = row.TableName;
}
_Conn = row.Conn;
if (!row[0].IsNullOrEmpty)
{
NewRow(true).LoadFrom(row);
//_Rows.Add(row);
}
}
}
/// <summary>
/// 转换成DataTable
/// </summary>
public DataTable ToDataTable()
{
DataTable dt = new DataTable(_TableName);
if (Columns != null && Columns.Count > 0)
{
bool checkDuplicate = Columns.CheckDuplicate;
List<string> duplicateName = new List<string>();
for (int j = 0; j < Columns.Count; j++)
{
MCellStruct item = Columns[j];
if (string.IsNullOrEmpty(item.ColumnName))
{
item.ColumnName = "Empty_" + item;
}
if (!checkDuplicate && dt.Columns.Contains(item.ColumnName))//去重。
{
string rndName = Guid.NewGuid().ToString();
dt.Columns.Add(rndName, item.ValueType);
duplicateName.Add(rndName);
continue;
}
dt.Columns.Add(item.ColumnName, item.ValueType);
}
int count = dt.Columns.Count;
foreach (MDataRow row in Rows)
{
DataRow dr = dt.NewRow();
for (int i = 0; i < count; i++)
{
if (row[i].IsNull)
{
dr[i] = DBNull.Value;
}
else
{
dr[i] = row[i].Value;
}
}
dt.Rows.Add(dr);
}
for (int i = 0; i < duplicateName.Count; i++)
{
dt.Columns.Remove(duplicateName[i]);
}
}
dt.AcceptChanges();
return dt;
}
/// <summary>
/// 输出Xml文档
/// </summary>
public string ToXml()
{
return ToXml(false);
}
public string ToXml(bool isConvertNameToLower)
{
return ToXml(isConvertNameToLower, true, true);
}
/// <summary>
/// 输出Xml文档
/// </summary>
/// <param name="isConvertNameToLower">名称转小写</param>
/// <returns></returns>
public string ToXml(bool isConvertNameToLower, bool needHeader, bool needRootNode)
{
StringBuilder xml = new StringBuilder();
if (Columns.Count > 0)
{
string tableName = string.IsNullOrEmpty(_TableName) ? "Root" : _TableName;
string rowName = string.IsNullOrEmpty(_TableName) ? "Row" : _TableName;
if (isConvertNameToLower)
{
tableName = tableName.ToLower();
rowName = rowName.ToLower();
}
if (needHeader)
{
xml.Append("<?xml version=\"1.0\" standalone=\"yes\"?>");
}
if (needRootNode)
{
xml.AppendFormat("\r\n<{0}>", tableName);
}
foreach (MDataRow row in Rows)
{
xml.AppendFormat("\r\n <{0}>", rowName);
foreach (MDataCell cell in row)
{
xml.Append(cell.ToXml(isConvertNameToLower));
}
xml.AppendFormat("\r\n </{0}>", rowName);
}
if (needRootNode)
{
xml.AppendFormat("\r\n</{0}>", tableName);
}
}
return xml.ToString();
}
public bool WriteXml(string fileName)
{
return WriteXml(fileName, false);
}
/// <summary>
/// 保存Xml
/// </summary>
public bool WriteXml(string fileName, bool isConvertNameToLower)
{
return IOHelper.Write(fileName, ToXml(isConvertNameToLower), Encoding.UTF8);
}
/// <summary>
/// 输出Json
/// </summary>
public string ToJson()
{
return ToJson(true);
}
public string ToJson(bool addHead)
{
return ToJson(addHead, false);
}
/// <param name="addHead">输出头部信息[带count、Success、ErrorMsg](默认true)</param>
/// <param name="addSchema">首行输出表架构信息,反接收时可还原架构(默认false)</param>
public string ToJson(bool addHead, bool addSchema)
{
return ToJson(addHead, addSchema, RowOp.None);
}
/// <param name="rowOp">过滤选项</param>
public string ToJson(bool addHead, bool addSchema, RowOp rowOp)
{
return ToJson(addHead, addSchema, rowOp, false);
}
public string ToJson(bool addHead, bool addSchema, RowOp rowOp, bool isConvertNameToLower)
{
return ToJson(addHead, addSchema, rowOp, isConvertNameToLower, JsonHelper.DefaultEscape);
}
/// <param name="op">符号转义选项</param>
public string ToJson(bool addHead, bool addSchema, RowOp rowOp, bool isConvertNameToLower, EscapeOp escapeOp)
{
JsonHelper helper = new JsonHelper(addHead, addSchema);
if (DynamicData != null && DynamicData is MDictionary<int, int>)
{
helper.LoopCheckList = DynamicData as MDictionary<int, int>;//继承父的数据,避免循环引用父
helper.Level = helper.LoopCheckList[helper.LoopCheckList.Count - 1] + 1;
}
helper.Escape = escapeOp;
helper.IsConvertNameToLower = isConvertNameToLower;
helper.RowOp = rowOp;
helper.Fill(this);
bool checkArrayEnd = !addHead && !addSchema;
return helper.ToString(checkArrayEnd);
}
/// <summary>
/// 输出Json[可指定保存路径]
/// </summary>
public bool WriteJson(bool addHead, bool addSchema, string fileName)
{
return IOHelper.Write(fileName, ToJson(addHead, addSchema));
}
/// <summary>
/// 将数据表绑定到列表控件
/// </summary>
/// <param name="control">列表控件[包括Repeater/DataList/GridView/DataGrid等]</param>
public void Bind(object control)
{
Bind(control, null);
}
/// <summary>
/// 将数据表绑定到列表控件
/// </summary>
/// <param name="control">列表控件[包括Repeater/DataList/GridView/DataGrid等]</param>
/// <param name="nodeid">当Control为XHtmlAction对象时,需要指定绑定的节点id</param>
public void Bind(object control, string nodeid)
{
MBindUI.Bind(control, this, nodeid);
}
/// <summary>
/// 将新表的行放到原表的下面。
/// </summary>
/// <param name="newTable"></param>
public void Merge(MDataTable newTable)
{
if (newTable != null && newTable.Rows.Count > 0)
{
int count = newTable.Rows.Count;//提前获取总数,是为了避免dt.Merge(dt);//加载自身导致的死循环。
for (int i = 0; i < count; i++)
{
// _Rows.Add(newTable.Rows[i]);
NewRow(true).LoadFrom(newTable.Rows[i]);
}
}
}
/// <summary>
/// 将表里所有行的数据行的状态全部重置
/// </summary>
/// <param name="state">状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]]</param>
public MDataTable SetState(int state)
{
SetState(state, BreakOp.None); return this;
}
/// <summary>
/// 将表里所有行的数据行的状态全部重置
/// </summary>
/// <param name="state">状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]]</param>
/// <param name="op">状态设置选项</param>
public MDataTable SetState(int state, BreakOp op)
{
if (Rows != null && Rows.Count > 0)
{
foreach (MDataRow row in Rows)
{
row.SetState(state, op);
}
}
return this;
}
/// <summary>
/// 转实体列表
/// </summary>
/// <param name="useEmit">是否使用Emit方式转换[数据越多[大于500条]性能越高],不写默认自适应判断</param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public List<T> ToList<T>(params bool[] useEmit)
{
List<T> list = new List<T>();
if (Rows != null && Rows.Count > 0)
{
if (((Rows.Count > 500 && useEmit.Length == 0) || (useEmit.Length > 0 && useEmit[0])) && typeof(T).BaseType.Name != "OrmBase")//远程代理实体的属性会变,无法用Emit
{
FastToT<T>.EmitHandle emit = FastToT<T>.Create(this);
foreach (MDataRow row in Rows)
{
list.Add(emit(row));
}
}
else
{
foreach (MDataRow row in Rows)
{
list.Add(row.ToEntity<T>());
}
}
}
return list;
}
internal object ToList(Type t)
{
if (t.Name == "MDataTable")
{
return this;
}
object listObj = Activator.CreateInstance(t);//创建实例
if (Rows != null && Rows.Count > 0)
{
Type[] paraTypeList = null;
Type listObjType = listObj.GetType();
ReflectTool.GetArgumentLength(ref listObjType, out paraTypeList);
MethodInfo method = listObjType.GetMethod("Add");
foreach (MDataRow row in Rows)
{
method.Invoke(listObj, new object[] { row.ToEntity(paraTypeList[0]) });
}
}
return listObj;
}
/// <summary>
/// 批量插入或更新 [提示:操作和当前表名有关,如当前表名不是要提交入库的表名,请给TableName属性重新赋值]
/// </summary>
/// <param name="op">操作选项[插入|更新]</param>
/// <returns>返回false时,若有异常,存在:DynamicData 参数中</returns>
public bool AcceptChanges(AcceptOp op)
{
return AcceptChanges(op, IsolationLevel.Unspecified, string.Empty);
}
/// <summary>
/// 批量插入或更新 [提示:操作和当前表名有关,如当前表名不是要提交入库的表名,请给TableName属性重新赋值]
/// </summary>
/// <param name="op">操作选项[插入|更新]</param>
/// <param name="tranLevel">事务等级【外部没有事务时有效】</param>
/// <returns>返回false时,若有异常,存在:DynamicData 参数中</returns>
public bool AcceptChanges(AcceptOp op, IsolationLevel tranLevel)
{
return AcceptChanges(op, tranLevel, string.Empty);
}
/// <param name="op">操作选项[插入|更新]</param>
/// <param name="newConn">指定新的数据库链接</param>
/// <param name="jointPrimaryKeys">AcceptOp为Update或Auto时,若需要设置联合主键为唯一检测或更新条件,则可设置多个字段名</param>
/// <returns>返回false时,若有异常,存在:DynamicData 参数中</returns>
public bool AcceptChanges(AcceptOp op, string newConn, params object[] jointPrimaryKeys)
{
return AcceptChanges(op, IsolationLevel.Unspecified, newConn, jointPrimaryKeys);
}
// <summary>
/// 批量插入或更新 [提示:操作和当前表名有关,如当前表名不是要提交入库的表名,请给TableName属性重新赋值]
/// </summary>
/// <param name="tranLevel">事务等级【外部没有事务时有效】</param>
/// <returns>返回false时,若有异常,存在:DynamicData 参数中</returns>
public bool AcceptChanges(AcceptOp op, IsolationLevel tranLevel, string newConn, params object[] jointPrimaryKeys)
{
bool result = false;
if (Columns.Count == 0 || Rows.Count == 0)
{
return false;//木有可更新的。
}
MDataTableBatchAction action = new MDataTableBatchAction(this, newConn);
action.TranLevel = tranLevel;
if ((op & AcceptOp.Truncate) != 0)
{
action.IsTruncate = true;
op = (AcceptOp)(op - AcceptOp.Truncate);
}
action.SetJoinPrimaryKeys(jointPrimaryKeys);
switch (op)
{
case AcceptOp.Insert:
result = action.Insert(false);
break;
case AcceptOp.InsertWithID:
result = action.Insert(true);
break;
case AcceptOp.Update:
result = action.Update();
break;
case AcceptOp.Delete:
result = action.Delete();
break;
case AcceptOp.Auto:
result = action.Auto();
break;
}
if (result && AppConfig.Cache.IsAutoCache)
{
//取消AOP缓存。
AutoCache.ReadyForRemove(AutoCache.GetBaseKey(TableName, newConn));
}
return result;
}
/// <summary>
/// 获取修改过的数据
/// </summary>
/// <returns></returns>
public MDataTable GetChanges()
{
return GetChanges(RowOp.Update);
}
/// <summary>
/// 获取修改过的数据(若无修改,则返回Null)
/// </summary>
/// <param name="rowOp">仅Insert和Update选项可用</param>
/// <returns></returns>
public MDataTable GetChanges(RowOp rowOp)
{
MDataTable dt = new MDataTable(_TableName);
dt.Columns = Columns;
dt.Conn = Conn;
dt.DynamicData = DynamicData;
dt.joinOnIndex = joinOnIndex;
dt.JoinOnName = dt.JoinOnName;
dt.RecordsAffected = RecordsAffected;
if (this.Rows.Count > 0)
{
if (rowOp == RowOp.Insert || rowOp == RowOp.Update)
{
int stateValue = (int)rowOp;
foreach (MDataRow row in Rows)
{
if (row.GetState() >= stateValue)
{
dt.Rows.Add(row, false);
}
}
}
}
return dt;
}
/// <summary>
/// 返回某列的集合
/// <param name="columnName">列名</param>
/// </summary>
public List<T> GetColumnItems<T>(string columnName)
{
return GetColumnItems<T>(columnName, BreakOp.None, false);
}
/// <summary>
/// 返回某列的集合
/// <param name="columnName">列名</param>
/// <param name="op">参数选项</param>
/// </summary>
public List<T> GetColumnItems<T>(string columnName, BreakOp op)
{
return GetColumnItems<T>(columnName, op, false);
}
/// <summary>
/// 返回某列的集合
/// </summary>
/// <typeparam name="T">列的类型</typeparam>
/// <param name="columnIndex">列名</param>
/// <param name="op">过滤选项</param>
/// <param name="isDistinct">是否去掉重复数据</param>
public List<T> GetColumnItems<T>(string columnName, BreakOp op, bool isDistinct)
{
int index = -1;
if (Columns != null)
{
index = Columns.GetIndex(columnName);
}
return GetColumnItems<T>(index, op, isDistinct);
}
/// <summary>
/// 返回某列的集合
/// </summary>
/// <typeparam name="T">列的类型</typeparam>
/// <param name="columnIndex">第N列</param>
public List<T> GetColumnItems<T>(int columnIndex)
{
return GetColumnItems<T>(columnIndex, BreakOp.None);
}
/// <summary>
/// 返回某列的集合
/// </summary>
/// <typeparam name="T">列的类型</typeparam>
/// <param name="columnIndex">第N列</param>
/// <param name="op">过滤选项</param>
/// <returns></returns>
public List<T> GetColumnItems<T>(int columnIndex, BreakOp op)
{
return GetColumnItems<T>(columnIndex, op, false);
}
/// <summary>
/// 返回某列的集合
/// </summary>
/// <typeparam name="T">列的类型</typeparam>
/// <param name="columnIndex">第N列</param>
/// <param name="op">过滤选项</param>
/// <param name="isDistinct">是否去掉重复数据</param>
public List<T> GetColumnItems<T>(int columnIndex, BreakOp op, bool isDistinct)
{
List<T> items = new List<T>();
if (Columns != null && Rows != null && Rows.Count > 0)
{
if (columnIndex > -1)
{
MDataCell cell;
foreach (MDataRow row in Rows)
{
cell = row[columnIndex];
switch (op)
{
case BreakOp.Null:
if (cell.IsNull)
{
continue;
}
break;
case BreakOp.Empty:
if (cell.StringValue == "")
{
continue;
}
break;
case BreakOp.NullOrEmpty:
if (cell.IsNullOrEmpty)
{
continue;
}
break;
}
T value = cell.Get<T>();// row.Get<T>(columnIndex, default(T));
if (!isDistinct || !items.Contains(value))
{
items.Add(value);
}
}
}
else
{
Error.Throw(string.Format("Table {0} can not find the column", TableName));
}
}
return items;
}
/// <summary>
/// 复制表
/// </summary>
public MDataTable Clone()
{
MDataTable newTable = GetSchema(true);
newTable.Conn = Conn;
newTable.DynamicData = DynamicData;
newTable.RecordsAffected = RecordsAffected;
newTable.TableName = TableName;
if (_Rows.Count > 0)
{
foreach (MDataRow oldRow in _Rows)
{
MDataRow newRow = newTable.NewRow();
newRow.LoadFrom(oldRow);
newTable.Rows.Add(newRow, false);
}
}
return newTable;
}
/// <summary>
/// 复制表的结构
/// </summary>
/// <param name="clone">是否克隆表结构</param>
/// <returns></returns>
public MDataTable GetSchema(bool clone)
{
MDataTable newTable = new MDataTable(_TableName);
if (Columns.Count > 0)
{
newTable.Columns = clone ? Columns.Clone() : Columns;
}
newTable.Conn = Conn;
return newTable;
}
/// <summary>
/// 过滤掉重复的数据行(仅比较基础类型、复杂数据类型仅比较类型名称)。
/// <param name="filterRows">被过滤的数据集表</param>
/// </summary>
public void Distinct(out MDataTable filterRows)
{
Distinct(out filterRows, true);
}
private void Distinct(out MDataTable filterRows, bool isNeedOut)
{
filterRows = null;
if (Rows.Count > 0)
{
List<MDataRow> rowList = new List<MDataRow>();
int cCount = Columns.Count;
for (int i = 0; i < Rows.Count; i++)
{
for (int j = Rows.Count - 1; j >= 0 && j != i; j--)//反序检测。
{
int eqCount = 0;
for (int k = 0; k < cCount; k++)//比较列
{
if (Rows[i][k].StringValue == Rows[j][k].StringValue)
{
eqCount++;
}
else
{
break;
}
}
if (eqCount == cCount)
{
if (isNeedOut)
{
rowList.Add(Rows[j]);
}
Rows.RemoveAt(j);
}
}
}
if (rowList.Count > 0)
{
filterRows = rowList;
filterRows.Columns = filterRows.Columns.Clone();//重置头部引用
Columns._Table = this;
}
}
}
/// <summary>
/// 过滤掉重复的数据行(仅比较基础类型、复杂数据类型仅比较类型名称)。
/// </summary>
public void Distinct()
{
MDataTable filterRows;
Distinct(out filterRows, false);
filterRows = null;
}
#endregion
public override string ToString()
{
return TableName;
}
}
public partial class MDataTable : IDataReader, IEnumerable//, IEnumerator
{
private int _Ptr = -1;//行索引
#region IDataRecord 成员
/// <summary>
/// 获取列的总数
/// </summary>
int IDataRecord.FieldCount
{
get
{
if (Columns != null)
{
return Columns.Count;
}
return 0;
}
}
bool IDataRecord.GetBoolean(int i)
{
return (bool)_Rows[_Ptr][i].Value;
}
byte IDataRecord.GetByte(int i)
{
return (byte)_Rows[_Ptr][i].Value;
}
long IDataRecord.GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
return (byte)_Rows[_Ptr][i].Value;
}
char IDataRecord.GetChar(int i)
{
return (char)_Rows[_Ptr][i].Value;
}
long IDataRecord.GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
return (char)_Rows[_Ptr][i].Value;