[DefaultProperty ("TableName")]
[DesignTimeVisible (false)]
[EditorAttribute ("Microsoft.VSDesigner.Data.Design.DataTableEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
- [TypeConverterAttribute("System.ComponentModel.ComponentConverter, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
[Serializable]
public class DataTable : MarshalByValueComponent, IListSource, ISupportInitialize, ISerializable
{
private bool _containsListCollection;
private string _encodedTableName;
internal bool _duringDataLoad;
+ internal bool _nullConstraintViolationDuringDataLoad;
private bool dataSetPrevEnforceConstraints;
private bool dataTablePrevEnforceConstraints;
private bool enforceConstraints = true;
// If CaseSensitive property is changed once it does not anymore follow owner DataSet's
// CaseSensitive property. So when you lost you virginity it's gone for ever
private bool _virginCaseSensitive = true;
+
+ /// <summary>
+ /// An enum variable indicating whether BeginInit() or EndInit() is called.
+ /// Delegate to call a function which performs cleanup after EndInit() is called
+ /// </summary>
+ internal enum initStatus { NotInitialized, BeginInit, EndInit };
+
+ private initStatus _initStatus;
+
+ private delegate void PostEndInit();
+
+ internal initStatus InitStatus{
+ get{ return( _initStatus ); }
+ }
+
/// <summary>
/// Initializes a new instance of the DataTable class with no arguments.
{
string schema = info.GetString ("XmlSchema");
string data = info.GetString ("XmlDiffGram");
-
+
+ DataSet ds = new DataSet ();
+ ds.ReadXmlSchema (new StringReader (schema));
+ ds.Tables [0].CopyProperties (this);
+ ds = new DataSet ();
+ ds.Tables.Add (this);
+ ds.ReadXml (new StringReader (data), XmlReadMode.IgnoreSchema);
+ ds.Tables.Remove (this);
+/* keeping for a while. With the change above, we shouldn't have to consider
+ * DataTable mode in schema inference/read.
XmlSchemaMapper mapper = new XmlSchemaMapper (this);
XmlTextReader xtr = new XmlTextReader(new StringReader (schema));
mapper.Read (xtr);
XmlDiffLoader loader = new XmlDiffLoader (this);
xtr = new XmlTextReader(new StringReader (data));
loader.Load (xtr);
+*/
}
-#if NET_1_2
+#if NET_2_0
public DataTable (string tableName, string tbNamespace)
: this (tableName)
{
/// </summary>
[DataSysDescription ("Indicates whether comparing strings within the table is case sensitive.")]
public bool CaseSensitive {
- get { return _caseSensitive; }
+ get {
+ if (_virginCaseSensitive && dataSet != null)
+ return dataSet.CaseSensitive;
+ else
+ return _caseSensitive;
+ }
set {
if (_childRelations.Count > 0 || _parentRelations.Count > 0) {
throw new ArgumentException ("Cannot change CaseSensitive or Locale property. This change would lead to at least one DataRelation or Constraint to have different Locale or CaseSensitive settings between its related tables.");
[DataSysDescription ("The expression used to compute the data-bound value of this row.")]
[DefaultValue ("")]
public string DisplayExpression {
- get { return "" + _displayExpression; }
+ get { return _displayExpression == null ? "" : _displayExpression; }
set { _displayExpression = value; }
}
[DataCategory ("Data")]
[DataSysDescription ("Indicates the XML uri namespace for the elements contained in this table.")]
public string Namespace {
- get { return "" + _nameSpace; }
+ get { return _nameSpace == null ? "" : _nameSpace; }
set { _nameSpace = value; }
}
[DataSysDescription ("Indicates the Prefix of the namespace used for this table in XML representation.")]
[DefaultValue ("")]
public string Prefix {
- get { return "" + _prefix; }
+ get { return _prefix == null ? "" : _prefix; }
set {
// Prefix cannot contain any special characters other than '_' and ':'
for (int i = 0; i < value.Length; i++) {
[DefaultValue ("")]
[RefreshProperties (RefreshProperties.All)]
public string TableName {
- get { return "" + _tableName; }
+ get { return _tableName == null ? "" : _tableName; }
set { _tableName = value; }
}
}
}
- public bool RowsExist(Object[] columns, Object[] relatedColumns,DataRow row)
+ internal bool RowsExist(Object[] columns, Object[] relatedColumns,DataRow row)
{
object[] vals = new object[relatedColumns.Length];
for (int i = 0; i < vals.Length; i++)
return RowsExist(columns,vals);
}
- public bool RowsExist(Object[] columns,Object[] values)
+ internal bool RowsExist(Object[] columns,Object[] values)
{
bool rowsExist = false;
Index indx = this.GetIndexByColumns ((DataColumn[])columns);
if (indx != null) { // lookup for a row in index
rowsExist = (indx.FindSimple (values, false) != null);
- } else { // no index we have to perform full-table scan
- // check that there is a parent for this row.
+ }
+
+ if(indx == null || rowsExist == false) {
+ // no index or rowExist= false, we have to perform full-table scan
+ // check that there is a parent for this row.
foreach (DataRow thisRow in this.Rows) {
if (thisRow.RowState != DataRowState.Deleted) {
bool match = true;
/// </summary>
public virtual void BeginInit ()
{
+ _initStatus = initStatus.BeginInit;
}
/// <summary>
//duringDataLoad is important to EndLoadData and
//for not throwing unexpected exceptions.
this._duringDataLoad = true;
+ this._nullConstraintViolationDuringDataLoad = false;
if (this.dataSet != null)
{
// have enforced child relations
// that would result in child rows being orphaned
// now we check if any ForeignKeyConstraint is referncing 'table'.
- if (DataSet._xmlDataDocument != null)
- throw new NotSupportedException ("Clear function on dataset and datatable is not supported on XmlDataDocument.");
if (DataSet != null)
{
+ if (DataSet._xmlDataDocument != null)
+ throw new NotSupportedException ("Clear function on dataset and datatable is not supported on XmlDataDocument.");
+
IEnumerator tableEnumerator = DataSet.Tables.GetEnumerator();
// loop on all tables in dataset
// Copy.DefaultView
// Copy.DesignMode
Copy.DisplayExpression = DisplayExpression;
- // Cannot copy extended properties directly as the property does not have a set accessor
- Array tgtArray = Array.CreateInstance( typeof (object), ExtendedProperties.Count);
- ExtendedProperties.Keys.CopyTo (tgtArray, 0);
- for (int i=0; i < ExtendedProperties.Count; i++)
- Copy.ExtendedProperties.Add (tgtArray.GetValue (i), ExtendedProperties[tgtArray.GetValue (i)]);
+ if(ExtendedProperties.Count > 0) {
+ // Cannot copy extended properties directly as the property does not have a set accessor
+ Array tgtArray = Array.CreateInstance( typeof (object), ExtendedProperties.Count);
+ ExtendedProperties.Keys.CopyTo (tgtArray, 0);
+ for (int i=0; i < ExtendedProperties.Count; i++)
+ Copy.ExtendedProperties.Add (tgtArray.GetValue (i), ExtendedProperties[tgtArray.GetValue (i)]);
+ }
Copy.Locale = Locale;
Copy.MinimumCapacity = MinimumCapacity;
Copy.Namespace = Namespace;
[MonoTODO]
public virtual void EndInit ()
{
+ _initStatus = initStatus.EndInit;
+ // Add the constraints
+ PostEndInit _postEndInit = new PostEndInit (_constraintCollection.PostEndInit);
+ _postEndInit();
+
}
//Getting back to the table's previous EnforceConstraint state
this.EnforceConstraints = this.dataTablePrevEnforceConstraints;
}
- for (i=0 ; i<this.Rows.Count ; i++)
- {
- if (this.Rows[i]._nullConstraintViolation )
- {
- throw new ConstraintException ("Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.");
- }
-
+
+ if(this._nullConstraintViolationDuringDataLoad) {
+ this._nullConstraintViolationDuringDataLoad = false;
+ throw new ConstraintException ("Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.");
}
+
//Returning from loading mode, raising exceptions as usual
this._duringDataLoad = false;
return copyTable;
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public DataTableReader GetDataReader ()
{
info.AddValue ("XmlDiffGram", sw.ToString(), typeof(string));
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public void Load (IDataReader reader)
{
return row;
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public DataRow LoadDataRow (object[] values, LoadOption loadOption)
{
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
XmlReadMode ReadXml (Stream stream)
{
if (sortableColumns.Length == 0)
throw new Exception("sort expression result is 0");
- RowSorter rowSorter = new RowSorter (dataRows, sortableColumns);
+ RowSorter rowSorter = new RowSorter (this, dataRows, sortableColumns);
dataRows = rowSorter.SortRows ();
sortableColumns = null;
return retVal;
}
-#if NET_1_2
+#if NET_2_0
[MonoTODO]
public void WriteXml (Stream stream)
{
// {
// RemoveColumn(this, e);
// }
+ this.Rows.onColumnRemoved(column.Ordinal);
}
/// <summary>
string columnName = columnSortInfo[0].Trim ();
string sortOrder = "ASC";
if (columnSortInfo.Length > 1)
- sortOrder = columnSortInfo[1].Trim ().ToUpper ();
+ sortOrder = columnSortInfo[1].Trim ().ToUpper (Locale);
ListSortDirection sortDirection = ListSortDirection.Ascending;
switch (sortOrder) {
private class RowSorter : IComparer
{
+ private DataTable table;
private SortableColumn[] sortColumns;
private DataRow[] rowsToSort;
- internal RowSorter(DataRow[] unsortedRows,
+ internal RowSorter(DataTable table,
+ DataRow[] unsortedRows,
SortableColumn[] sortColumns)
{
+ this.table = table;
this.sortColumns = sortColumns;
this.rowsToSort = unsortedRows;
}
return 1;
if((a is string) && (b is string)) {
- a = ((string) a).ToUpper ();
- b = ((string) b).ToUpper ();
+ a = ((string) a).ToUpper (table.Locale);
+ b = ((string) b).ToUpper (table.Locale);
}
if (a is IComparable)