DataRowCollection.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //------------------------------------------------------------------------------
  2. // <copyright file="DataRowCollection.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. // <owner current="false" primary="false">[....]</owner>
  8. //------------------------------------------------------------------------------
  9. namespace System.Data {
  10. using System;
  11. using System.Collections;
  12. using System.ComponentModel;
  13. using System.Diagnostics;
  14. public sealed class DataRowCollection : InternalDataCollectionBase {
  15. private sealed class DataRowTree : RBTree<DataRow> {
  16. internal DataRowTree() : base(TreeAccessMethod.INDEX_ONLY) {
  17. }
  18. protected override int CompareNode (DataRow record1, DataRow record2) {
  19. throw ExceptionBuilder.InternalRBTreeError(RBTreeError.CompareNodeInDataRowTree);
  20. }
  21. protected override int CompareSateliteTreeNode (DataRow record1, DataRow record2) {
  22. throw ExceptionBuilder.InternalRBTreeError(RBTreeError.CompareSateliteTreeNodeInDataRowTree);
  23. }
  24. }
  25. private readonly DataTable table;
  26. private readonly DataRowTree list = new DataRowTree();
  27. internal int nullInList = 0;
  28. /// <devdoc>
  29. /// Creates the DataRowCollection for the given table.
  30. /// </devdoc>
  31. internal DataRowCollection(DataTable table) {
  32. this.table = table;
  33. }
  34. public override int Count {
  35. get {
  36. return list.Count;
  37. }
  38. }
  39. /// <devdoc>
  40. /// <para>Gets the row at the specified index.</para>
  41. /// </devdoc>
  42. public DataRow this[int index] {
  43. get {
  44. return list[index];
  45. }
  46. }
  47. /// <devdoc>
  48. /// <para>Adds the specified <see cref='System.Data.DataRow'/> to the <see cref='System.Data.DataRowCollection'/> object.</para>
  49. /// </devdoc>
  50. public void Add(DataRow row) {
  51. table.AddRow(row, -1);
  52. }
  53. public void InsertAt(DataRow row, int pos) {
  54. if (pos < 0)
  55. throw ExceptionBuilder.RowInsertOutOfRange(pos);
  56. if (pos >= list.Count)
  57. table.AddRow(row, -1);
  58. else
  59. table.InsertRow(row, -1, pos);
  60. }
  61. internal void DiffInsertAt(DataRow row, int pos) {
  62. if ((pos < 0) || (pos == list.Count)) {
  63. table.AddRow(row, pos >-1? pos+1 : -1);
  64. return;
  65. }
  66. if (table.NestedParentRelations.Length > 0) { // get in this trouble only if table has a nested parent
  67. // get into trouble if table has JUST a nested parent? how about multi parent!
  68. if (pos < list.Count) {
  69. if (list[pos] != null) {
  70. throw ExceptionBuilder.RowInsertTwice(pos, table.TableName);
  71. }
  72. list.RemoveAt(pos);
  73. nullInList--;
  74. table.InsertRow(row, pos+1, pos);
  75. }
  76. else {
  77. while (pos>list.Count) {
  78. list.Add(null);
  79. nullInList++;
  80. }
  81. table.AddRow(row, pos+1);
  82. }
  83. }
  84. else {
  85. table.InsertRow(row, pos+1, pos > list.Count ? -1 : pos);
  86. }
  87. }
  88. public Int32 IndexOf(DataRow row) {
  89. if ((null == row) || (row.Table != this.table) || ((0 == row.RBTreeNodeId) && (row.RowState == DataRowState.Detached))) //Webdata 102857
  90. return -1;
  91. return list.IndexOf(row.RBTreeNodeId, row);
  92. }
  93. /// <devdoc>
  94. /// <para>Creates a row using specified values and adds it to the
  95. /// <see cref='System.Data.DataRowCollection'/>.</para>
  96. /// </devdoc>
  97. internal DataRow AddWithColumnEvents(params object[] values) {
  98. DataRow row = table.NewRow(-1);
  99. row.ItemArray = values;
  100. table.AddRow(row, -1);
  101. return row;
  102. }
  103. public DataRow Add(params object[] values) {
  104. int record = table.NewRecordFromArray(values);
  105. DataRow row = table.NewRow(record);
  106. table.AddRow(row, -1);
  107. return row;
  108. }
  109. internal void ArrayAdd(DataRow row) {
  110. row.RBTreeNodeId = list.Add(row);
  111. }
  112. internal void ArrayInsert(DataRow row, int pos) {
  113. row.RBTreeNodeId = list.Insert(pos, row);
  114. }
  115. internal void ArrayClear() {
  116. list.Clear();
  117. }
  118. internal void ArrayRemove(DataRow row) {
  119. if (row.RBTreeNodeId == 0) {
  120. throw ExceptionBuilder.InternalRBTreeError(RBTreeError.AttachedNodeWithZerorbTreeNodeId);
  121. }
  122. list.RBDelete(row.RBTreeNodeId);
  123. row.RBTreeNodeId = 0;
  124. }
  125. /// <devdoc>
  126. /// <para>Gets
  127. /// the row specified by the primary key value.
  128. /// </para>
  129. /// </devdoc>
  130. public DataRow Find(object key) {
  131. return table.FindByPrimaryKey(key);
  132. }
  133. /// <devdoc>
  134. /// <para>Gets the row containing the specified primary key values.</para>
  135. /// </devdoc>
  136. public DataRow Find(object[] keys) {
  137. return table.FindByPrimaryKey(keys);
  138. }
  139. /// <devdoc>
  140. /// <para>Clears the collection of all rows.</para>
  141. /// </devdoc>
  142. public void Clear() {
  143. table.Clear(false);
  144. }
  145. /// <devdoc>
  146. /// <para>
  147. /// Gets a value indicating whether the primary key of any row in the
  148. /// collection contains the specified value.
  149. /// </para>
  150. /// </devdoc>
  151. public bool Contains(object key) {
  152. return(table.FindByPrimaryKey(key) != null);
  153. }
  154. /// <devdoc>
  155. /// <para>
  156. /// Gets a value indicating if the <see cref='System.Data.DataRow'/> with
  157. /// the specified primary key values exists.
  158. /// </para>
  159. /// </devdoc>
  160. public bool Contains(object[] keys) {
  161. return(table.FindByPrimaryKey(keys) != null);
  162. }
  163. public override void CopyTo(Array ar, int index) {
  164. list.CopyTo(ar, index);
  165. }
  166. public void CopyTo(DataRow[] array, int index) {
  167. list.CopyTo(array, index);
  168. }
  169. public override IEnumerator GetEnumerator() {
  170. return list.GetEnumerator();
  171. }
  172. /// <devdoc>
  173. /// <para>Removes the specified <see cref='System.Data.DataRow'/> from the collection.</para>
  174. /// </devdoc>
  175. public void Remove(DataRow row) {
  176. if ((null == row) || (row.Table != table) || (-1 == row.rowID)) {
  177. throw ExceptionBuilder.RowOutOfRange();
  178. }
  179. if ((row.RowState != DataRowState.Deleted) && (row.RowState != DataRowState.Detached))
  180. row.Delete();
  181. if (row.RowState != DataRowState.Detached)
  182. row.AcceptChanges();
  183. }
  184. /// <devdoc>
  185. /// <para>
  186. /// Removes the row with the specified index from
  187. /// the collection.
  188. /// </para>
  189. /// </devdoc>
  190. public void RemoveAt(int index) {
  191. Remove(this[index]);
  192. }
  193. }
  194. }