DataKey.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //------------------------------------------------------------------------------
  2. // <copyright file="DataKey.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.Diagnostics;
  12. using System.ComponentModel;
  13. internal struct DataKey {
  14. private const int maxColumns = 32;
  15. private readonly DataColumn[] columns;
  16. /// <devdoc>
  17. /// <para>[To be supplied.]</para>
  18. /// </devdoc>
  19. internal DataKey(DataColumn[] columns, bool copyColumns) {
  20. if (columns == null)
  21. throw ExceptionBuilder.ArgumentNull("columns");
  22. if (columns.Length == 0)
  23. throw ExceptionBuilder.KeyNoColumns();
  24. if (columns.Length > maxColumns)
  25. throw ExceptionBuilder.KeyTooManyColumns(maxColumns);
  26. for (int i = 0; i < columns.Length; i++) {
  27. if (columns[i] == null)
  28. throw ExceptionBuilder.ArgumentNull("column");
  29. }
  30. for (int i = 0; i < columns.Length; i++) {
  31. for (int j = 0; j < i; j++) {
  32. if (columns[i] == columns[j]) {
  33. throw ExceptionBuilder.KeyDuplicateColumns(columns[i].ColumnName);
  34. }
  35. }
  36. }
  37. if (copyColumns) {
  38. // Need to make a copy of all columns
  39. this.columns = new DataColumn [columns.Length];
  40. for (int i = 0; i < columns.Length; i++)
  41. this.columns[i] = columns[i];
  42. }
  43. else {
  44. // take ownership of the array passed in
  45. this.columns = columns;
  46. }
  47. CheckState();
  48. }
  49. internal DataColumn[] ColumnsReference {
  50. get {
  51. return columns;
  52. }
  53. }
  54. internal bool HasValue {
  55. get {
  56. return (null != columns);
  57. }
  58. }
  59. internal DataTable Table {
  60. get {
  61. return columns[0].Table;
  62. }
  63. }
  64. internal void CheckState() {
  65. DataTable table = columns[0].Table;
  66. if (table == null) {
  67. throw ExceptionBuilder.ColumnNotInAnyTable();
  68. }
  69. for (int i = 1; i < columns.Length; i++) {
  70. if (columns[i].Table == null) {
  71. throw ExceptionBuilder.ColumnNotInAnyTable();
  72. }
  73. if (columns[i].Table != table) {
  74. throw ExceptionBuilder.KeyTableMismatch();
  75. }
  76. }
  77. }
  78. //check to see if this.columns && key2's columns are equal regardless of order
  79. internal bool ColumnsEqual(DataKey key) {
  80. return ColumnsEqual(this.columns, ((DataKey)key).columns);
  81. }
  82. //check to see if columns1 && columns2 are equal regardless of order
  83. internal static bool ColumnsEqual(DataColumn[] column1, DataColumn[] column2) {
  84. if (column1 == column2) {
  85. return true;
  86. } else if (column1 == null || column2 == null) {
  87. return false;
  88. } else if (column1.Length != column2.Length) {
  89. return false;
  90. } else {
  91. int i, j;
  92. for (i=0; i<column1.Length; i++) {
  93. bool check = false;
  94. for (j=0; j<column2.Length; j++) {
  95. if (column1[i].Equals(column2[j])) {
  96. check = true;
  97. break;
  98. }
  99. }
  100. if (!check) {
  101. return false;
  102. }
  103. }
  104. }
  105. return true;
  106. }
  107. internal bool ContainsColumn(DataColumn column) {
  108. for (int i = 0; i < columns.Length; i++) {
  109. if (column == columns[i]) {
  110. return true;
  111. }
  112. }
  113. return false;
  114. }
  115. public override int GetHashCode() {
  116. Debug.Assert(false, "don't put DataKey into a Hashtable");
  117. return base.GetHashCode();
  118. }
  119. public static bool operator==(DataKey x, DataKey y) {
  120. return x.Equals((object)y);
  121. }
  122. public static bool operator!=(DataKey x, DataKey y) {
  123. return !x.Equals((object)y);
  124. }
  125. public override bool Equals(object value) {
  126. Debug.Assert(false, "need to directly call Equals(DataKey)");
  127. return Equals((DataKey)value);
  128. }
  129. internal bool Equals(DataKey value) {
  130. //check to see if this.columns && key2's columns are equal...
  131. DataColumn[] column1=this.columns;
  132. DataColumn[] column2=value.columns;
  133. if (column1 == column2) {
  134. return true;
  135. }
  136. else if (column1 == null || column2 == null) {
  137. return false;
  138. }
  139. else if (column1.Length != column2.Length) {
  140. return false;
  141. }
  142. else {
  143. for (int i = 0; i <column1.Length; i++) {
  144. if (!column1[i].Equals(column2[i])) {
  145. return false;
  146. }
  147. }
  148. return true;
  149. }
  150. }
  151. internal string[] GetColumnNames() {
  152. string[] values = new string[columns.Length];
  153. for(int i = 0; i < columns.Length; ++i) {
  154. values[i] = columns[i].ColumnName;
  155. }
  156. return values;
  157. }
  158. internal IndexField[] GetIndexDesc() {
  159. IndexField[] indexDesc = new IndexField[columns.Length];
  160. for (int i = 0; i < columns.Length; i++) {
  161. indexDesc[i] = new IndexField(columns[i], false);
  162. }
  163. return indexDesc;
  164. }
  165. internal object[] GetKeyValues(int record) {
  166. object[] values = new object[columns.Length];
  167. for (int i = 0; i < columns.Length; i++) {
  168. values[i] = columns[i][record];
  169. }
  170. return values;
  171. }
  172. internal Index GetSortIndex() {
  173. return GetSortIndex(DataViewRowState.CurrentRows);
  174. }
  175. internal Index GetSortIndex(DataViewRowState recordStates) {
  176. IndexField[] indexDesc = GetIndexDesc();
  177. return columns[0].Table.GetIndex(indexDesc, recordStates, (IFilter)null);
  178. }
  179. internal bool RecordsEqual(int record1, int record2) {
  180. for (int i = 0; i < columns.Length; i++) {
  181. if (columns[i].Compare(record1, record2) != 0) {
  182. return false;
  183. }
  184. }
  185. return true;
  186. }
  187. internal DataColumn[] ToArray() {
  188. DataColumn[] values = new DataColumn[columns.Length];
  189. for(int i = 0; i < columns.Length; ++i) {
  190. values[i] = columns[i];
  191. }
  192. return values;
  193. }
  194. }
  195. }