Example #1
0
 /// <summary>
 /// Creates all tables of the configuration database.
 /// </summary>
 private void CreateAllTables()
 {
     AllTables = new IBaseTable[]
     {
         CmdTypeTable   = new BaseTable <CmdType>("CmdType", "CmdTypeID", CommonPhrases.CmdTypeTable),
         CmdValTable    = new BaseTable <CmdVal>("CmdVal", "CmdValID", CommonPhrases.CmdValTable),
         CnlTypeTable   = new BaseTable <CnlType>("CnlType", "CnlTypeID", CommonPhrases.CnlTypeTable),
         CommLineTable  = new BaseTable <CommLine>("CommLine", "CommLineNum", CommonPhrases.CommLineTable),
         CtrlCnlTable   = new BaseTable <CtrlCnl>("CtrlCnl", "CtrlCnlNum", CommonPhrases.CtrlCnlTable),
         EvTypeTable    = new BaseTable <EvType>("EvType", "CnlStatus", CommonPhrases.EvTypeTable),
         FormatTable    = new BaseTable <Format>("Format", "FormatID", CommonPhrases.FormatTable),
         FormulaTable   = new BaseTable <Formula>("Formula", "FormulaID", CommonPhrases.FormulaTable),
         InCnlTable     = new BaseTable <InCnl>("InCnl", "CnlNum", CommonPhrases.InCnlTable),
         InterfaceTable = new BaseTable <Data.Entities.Interface>("Interface", "ItfID",
                                                                  CommonPhrases.InterfaceTable),
         KPTable      = new BaseTable <KP>("KP", "KPNum", CommonPhrases.KPTable),
         KPTypeTable  = new BaseTable <KPType>("KPType", "KPTypeID", CommonPhrases.KPTypeTable),
         ObjTable     = new BaseTable <Obj>("Obj", "ObjNum", CommonPhrases.ObjTable),
         ParamTable   = new BaseTable <Param>("Param", "ParamID", CommonPhrases.ParamTable),
         RightTable   = new BaseTable <Right>("Right", "RightID", CommonPhrases.RightTable),
         RoleTable    = new BaseTable <Role>("Role", "RoleID", CommonPhrases.RoleTable),
         RoleRefTable = new BaseTable <RoleRef>("RoleRef", "RoleRefID", CommonPhrases.RoleRefTable),
         UnitTable    = new BaseTable <Unit>("Unit", "UnitID", CommonPhrases.UnitTable),
         UserTable    = new BaseTable <User>("User", "UserID", CommonPhrases.UserTable)
     };
 }
Example #2
0
    public IBaseTable GetTable(string name)
    {
        if (tableDic.ContainsKey(name))
        {
            return(tableDic[name]);
        }

        IBaseTable table = null;

#if UNITY_EDITOR
        const string path  = "Assets/Resources/Config/";
        var          asset = AssetDatabase.LoadAssetAtPath(path + name + ".asset", typeof(IBaseTable));
        if (asset == null)
        {
            Debug.LogError($"LoadTable-> {name} asset is null");
            return(null);
        }
        //使用实例化的Copy  防止Editor模式下 更改配置
        table = Object.Instantiate(asset) as IBaseTable;
#else
        table = Resources.Load("Config/" + name) as BaseTable;
#endif
        if (table == null)
        {
            Debug.LogError($"LoadTable-> {name} is null");
        }
        else
        {
            tableDic.Add(name, table);
        }
        return(table);
    }
Example #3
0
 /// <summary>
 /// Creates a new column that hosts cells which values are selected from a combo box.
 /// </summary>
 private static DataGridViewColumn NewComboBoxColumn(string dataPropertyName,
                                                     string displayMember, IBaseTable dataSource, bool addEmptyRow = false, bool prependID = false,
                                                     ColumnOptions options = null)
 {
     return(NewComboBoxColumn(dataPropertyName, dataPropertyName,
                              displayMember, dataSource, addEmptyRow, prependID, options));
 }
Example #4
0
        /// <summary>
        /// Downloads the table of the configuration database.
        /// </summary>
        public bool DownloadBaseTable(IBaseTable baseTable)
        {
            if (baseTable == null)
            {
                throw new ArgumentNullException(nameof(baseTable));
            }

            DownloadFile(
                new RelativePath(TopFolder.Base, AppFolder.Root, baseTable.FileNameDat),
                0, 0, false, DateTime.MinValue, () => { return(new MemoryStream()); },
                out _, out FileReadingResult readingResult, out Stream stream);

            try
            {
                if (readingResult == FileReadingResult.EndOfFile && stream != null)
                {
                    stream.Position = 0;
                    BaseTableAdapter adapter = new BaseTableAdapter()
                    {
                        Stream = stream
                    };
                    adapter.Fill(baseTable);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            finally
            {
                stream?.Dispose();
            }
        }
Example #5
0
        /// <summary>
        /// Calculates a start channel number.
        /// </summary>
        private bool CalcStartCnlNum(IBaseTable cnlTable, int cnlCnt, out int startCnlNum)
        {
            ChannelOptions channelOptions = appSettings.ChannelOptions;
            int            cnlMult        = channelOptions.CnlMult;
            int            cnlGap         = channelOptions.CnlGap;

            startCnlNum = cnlMult + channelOptions.CnlShift;
            int prevCnlNum = 0;

            foreach (int cnlNum in cnlTable.EnumerateKeys())
            {
                if (prevCnlNum < startCnlNum && startCnlNum <= cnlNum)
                {
                    if (startCnlNum + cnlCnt + cnlGap <= cnlNum)
                    {
                        return(true);
                    }
                    else
                    {
                        startCnlNum += cnlMult;
                    }
                }

                prevCnlNum = cnlNum;
            }

            return(startCnlNum <= ushort.MaxValue);
        }
Example #6
0
        /// <summary>
        /// Creates a data table for using as a data source of a combo box.
        /// </summary>
        private static DataTable CreateComboBoxSource(
            IBaseTable baseTable, string valueMember, ref string displayMember, bool addEmptyRow, bool prependID)
        {
            DataTable dataTable = baseTable.ToDataTable(true);

            if (prependID)
            {
                // display ID and name
                string columnName = valueMember + "_" + displayMember;
                dataTable.Columns.Add(columnName, typeof(string),
                                      string.Format("'[' + {0} + '] ' + {1}", valueMember, displayMember));
                displayMember = columnName;
                dataTable.DefaultView.Sort = valueMember;
            }
            else
            {
                dataTable.DefaultView.Sort = displayMember;
            }

            if (addEmptyRow)
            {
                DataRow emptyRow = dataTable.NewRow();
                emptyRow[valueMember]   = DBNull.Value;
                emptyRow[displayMember] = " ";
                dataTable.Rows.Add(emptyRow);
            }

            return(dataTable);
        }
Example #7
0
        /// <summary>
        /// Downloads the configuration database.
        /// </summary>
        private void DownloadBase()
        {
            transferControl.ThrowIfCancellationRequested();
            transferControl.WriteLine();
            transferControl.WriteMessage(AdminPhrases.DownloadBase);

            GetTempFileName(out string tempFileName, out string extractDir);
            agentClient.DownloadConfig(tempFileName, TopFolder.Base);
            ExtractArchive(tempFileName, extractDir, false);

            foreach (IBaseTable baseTable in project.ConfigDatabase.AllTables)
            {
                transferControl.ThrowIfCancellationRequested();
                transferControl.WriteMessage(string.Format(ExtensionPhrases.ImportTable, baseTable.Name));
                string datFileName = Path.Combine(extractDir, "BaseDAT", baseTable.FileNameDat);

                if (File.Exists(datFileName))
                {
                    BaseTableAdapter baseAdapter = new() { FileName = datFileName };
                    IBaseTable       srcTable    = BaseTableFactory.GetBaseTable(baseTable);
                    baseAdapter.Fill(srcTable);
                    baseTable.Modified = true;

                    foreach (object item in srcTable.EnumerateItems())
                    {
                        baseTable.AddObject(item);
                    }
                }
            }

            progressTracker.TaskIndex++;
        }
Example #8
0
        /// <summary>
        /// Imports the configuration database table.
        /// </summary>
        private void ImportBaseTable(DataTable srcTable, IBaseTable destTable)
        {
            // add primary keys if needed
            if (!srcTable.Columns.Contains(destTable.PrimaryKey))
            {
                srcTable.Columns.Add(destTable.PrimaryKey, typeof(int));
                srcTable.BeginLoadData();
                int colInd = srcTable.Columns.Count - 1;
                var id     = 1;

                foreach (DataRow row in srcTable.Rows)
                {
                    row[colInd] = id++;
                }

                srcTable.EndLoadData();
                srcTable.AcceptChanges();
            }

            // merge data
            destTable.Modified = true;
            var destProps = TypeDescriptor.GetProperties(destTable.ItemType);

            foreach (DataRowView srcRowView in srcTable.DefaultView)
            {
                object destItem = TableConverter.CreateItem(destTable.ItemType, srcRowView.Row, destProps);
                destTable.AddObject(destItem);
            }
        }
Example #9
0
        /// <summary>
        /// Imports the table.
        /// </summary>
        private bool Import(IBaseTable baseTable, BaseTableFormat format)
        {
            try
            {
                string srcfileName = openFileDialog.FileName;
                int    srcStartID  = chkSrcStartID.Checked ? Convert.ToInt32(numSrcStartID.Value) : 0;

                if (File.Exists(srcfileName))
                {
                    new ImportExport().ImportBaseTable(srcfileName, format, baseTable,
                                                       srcStartID,
                                                       chkSrcEndID.Checked ? Convert.ToInt32(numSrcEndID.Value) : int.MaxValue,
                                                       chkDestStartID.Checked ? Convert.ToInt32(numDestStartID.Value) : srcStartID,
                                                       out int affectedRows);
                    ScadaUiUtils.ShowInfo(string.Format(AppPhrases.ImportTableComplete, affectedRows));
                    return(true);
                }
                else
                {
                    ScadaUiUtils.ShowError(CommonPhrases.FileNotFound);
                    return(false);
                }
            }
            catch (Exception ex)
            {
                appData.ProcError(ex, string.Format(AdminPhrases.ImportBaseTableError, baseTable.Name));
                return(false);
            }
        }
Example #10
0
    static bool DeSerializeAsset(string[] rows, ref ScriptableObject obj)
    {
        IBaseTable table = (IBaseTable)obj;

        if (table == null)
        {
            Debug.LogError("it's not a BaseTable Type");
            return(false);
        }

        string[] lines = new string[rows.Length - 2];

        int index = 0;

        for (int i = 2; i < rows.Length; i++)
        {
            lines[index] = rows[i];
            index++;
        }

        string[] name = rows[0].Split(',');
        string[] type = rows[1].Split(',');
        table.DeSerialize(name, type, lines);
        return(true);
    }
Example #11
0
        /// <summary>
        /// Creates a node that represents the table of the configuration database.
        /// </summary>
        private TreeNode CreateBaseTableNode(IBaseTable baseTable)
        {
            TreeNode baseTableNode = TreeViewUtils.CreateNode(baseTable.Title, "table.png");

            baseTableNode.Tag = CreateBaseTableTag(baseTable);
            BaseTableNodes.Add(baseTable.Name, baseTableNode);
            return(baseTableNode);
        }
Example #12
0
        /// <summary>
        /// Adds a relation to the configuration database.
        /// </summary>
        protected void AddRelation(IBaseTable parentTable, IBaseTable childTable, string childColumn)
        {
            TableRelation relation = new TableRelation(parentTable, childTable, childColumn);

            childTable.AddIndex(childColumn);
            childTable.DependsOn.Add(relation);
            parentTable.Dependent.Add(relation);
        }
Example #13
0
        /// <summary>
        /// Inserts rows in the configuration database table.
        /// </summary>
        private void InsertRows(IBaseTable baseTable, NpgsqlTransaction trans)
        {
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(baseTable.ItemType);
            int propCnt = props.Count;

            if (propCnt == 0 || baseTable.ItemCount == 0)
            {
                return;
            }

            // create INSERT script like
            // INSERT INTO tablename (col1, col2) VALUES (@Col1, @Col2);
            StringBuilder sbSql1 = new();
            StringBuilder sbSql2 = new();

            sbSql1.Append("INSERT INTO ").Append(GetBaseTableName(baseTable)).Append(" (");
            sbSql2.Append("VALUES (");

            for (int i = 0; i < propCnt; i++)
            {
                if (i > 0)
                {
                    sbSql1.Append(", ");
                    sbSql2.Append(", ");
                }

                PropertyDescriptor prop = props[i];
                sbSql1.Append(GetBaseColumnName(prop));
                sbSql2.Append('@').Append(prop.Name);
            }

            sbSql1.Append(") ");
            sbSql2.Append(");");

            // create INSERT command
            string        sql = sbSql1.ToString() + sbSql2.ToString();
            NpgsqlCommand cmd = new(sql, conn, trans);

            foreach (PropertyDescriptor prop in props)
            {
                cmd.Parameters.Add(prop.Name, GetDbType(prop.PropertyType));
            }

            // execute command for table items
            bool filterByObj = uploadOptions.ObjectFilter.Count > 0 &&
                               (baseTable.ItemType == typeof(Cnl) || baseTable.ItemType == typeof(View));

            foreach (object item in filterByObj ?
                     SelectItems(baseTable, uploadOptions.ObjectFilter) : baseTable.EnumerateItems())
            {
                for (int i = 0; i < propCnt; i++)
                {
                    cmd.Parameters[i].Value = props[i].GetValue(item) ?? DBNull.Value;
                }

                cmd.ExecuteNonQuery();
            }
        }
Example #14
0
        /// <summary>
        /// Exports the configuration database table to the file.
        /// </summary>
        public void ExportBaseTable(string destFileName, BaseTableFormat format, IBaseTable baseTable,
                                    int startID, int endID)
        {
            if (destFileName == null)
            {
                throw new ArgumentNullException("destFileName");
            }
            if (baseTable == null)
            {
                throw new ArgumentNullException("baseTable");
            }

            IBaseTable destTable;

            if (0 < startID || endID < int.MaxValue)
            {
                // filter data
                destTable = BaseTableFactory.GetBaseTable(baseTable);

                if (startID <= endID)
                {
                    foreach (object item in baseTable.EnumerateItems())
                    {
                        int itemID = baseTable.GetPkValue(item);
                        if (startID <= itemID && itemID <= endID)
                        {
                            destTable.AddObject(item);
                        }
                        else if (itemID > endID)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                destTable = baseTable;
            }

            switch (format)
            {
            case BaseTableFormat.DAT:
                new BaseAdapter()
                {
                    FileName = destFileName
                }.Update(destTable);
                break;

            case BaseTableFormat.XML:
                destTable.Save(destFileName);
                break;

            default:     // BaseTableFormat.CSV
                new CsvConverter(destFileName).ConvertToCsv(destTable);
                break;
            }
        }
Example #15
0
        /// <summary>
        /// Loads the configuration database table.
        /// </summary>
        private void LoadBaseTable(IBaseTable baseTable, string baseDir)
        {
            string fileName = Path.Combine(baseDir, baseTable.FileName);

            if (File.Exists(fileName))
            {
                baseTable.Load(fileName);
            }
        }
Example #16
0
        /// <summary>
        /// Reads the table of the configuration database.
        /// </summary>
        public override void ReadBaseTable(IBaseTable baseTable)
        {
            BaseTableAdapter adapter = new BaseTableAdapter
            {
                FileName = Path.Combine(baseDir, baseTable.FileNameDat)
            };

            adapter.Fill(baseTable);
        }
Example #17
0
 /// <summary>
 /// Creates a tag to associate with a tree node representing a table.
 /// </summary>
 private TreeNodeTag CreateBaseTableTag(IBaseTable baseTable, TableFilter tableFilter = null)
 {
     return(new TreeNodeTag
     {
         FormType = typeof(FrmBaseTable),
         FormArgs = new object[] { baseTable, tableFilter, project, appData },
         RelatedObject = new BaseTableItem(baseTable, tableFilter),
         NodeType = AppNodeType.BaseTable
     });
 }
Example #18
0
        /// <summary>
        /// Converts the specified configuration database table to CSV.
        /// </summary>
        public void ConvertToCsv(IBaseTable baseTable)
        {
            if (baseTable == null)
            {
                throw new ArgumentNullException("baseTable");
            }

            Stream       stream = GetStream();
            StreamWriter writer = null;

            try
            {
                if (baseTable.ItemCount > 0)
                {
                    // prepare a writer
                    writer = new StreamWriter(stream, Encoding.Default);

                    // output the table header
                    PropertyDescriptorCollection props = TypeDescriptor.GetProperties(baseTable.ItemType);
                    int propCnt = props.Count;
                    for (int i = 0; i < propCnt; i++)
                    {
                        if (i > 0)
                        {
                            writer.Write(";");
                        }
                        writer.Write("[" + props[i].Name + "]");
                    }
                    writer.WriteLine();

                    // output the table rows
                    foreach (object item in baseTable.EnumerateItems())
                    {
                        for (int i = 0; i < propCnt; i++)
                        {
                            if (i > 0)
                            {
                                writer.Write(";");
                            }
                            WriteValue(writer, props[i].GetValue(item));
                        }
                        writer.WriteLine();
                    }
                }
            }
            finally
            {
                if (fileMode)
                {
                    writer?.Dispose();
                    stream?.Dispose();
                }
            }
        }
        /// <summary>
        /// Reads the configuration database table.
        /// </summary>
        public static void ReadBaseTable(IBaseTable baseTable, NpgsqlConnection conn)
        {
            string        sql = "SELECT * from " + GetBaseTableName(baseTable);
            NpgsqlCommand cmd = new NpgsqlCommand(sql, conn);

            using (NpgsqlDataReader reader = cmd.ExecuteReader())
            {
                if (reader.HasRows)
                {
                    // check primary key column
                    try
                    {
                        reader.GetOrdinal(GetBaseColumnName(baseTable.PrimaryKey, false));
                    }
                    catch
                    {
                        throw new ScadaException(Locale.IsRussian ?
                                                 "Первичный ключ \"{0}\" не найден" :
                                                 "Primary key \"{0}\" not found", baseTable.PrimaryKey);
                    }

                    // find column indexes
                    PropertyDescriptorCollection props = TypeDescriptor.GetProperties(baseTable.ItemType);
                    int   propCnt = props.Count;
                    int[] colIdxs = new int[propCnt];

                    for (int i = 0; i < propCnt; i++)
                    {
                        try { colIdxs[i] = reader.GetOrdinal(GetBaseColumnName(props[i], false)); }
                        catch { colIdxs[i] = -1; }
                    }

                    // read rows
                    baseTable.Modified = true;

                    while (reader.Read())
                    {
                        object item = baseTable.NewItem();

                        for (int i = 0; i < propCnt; i++)
                        {
                            int colIdx = colIdxs[i];

                            if (colIdx >= 0 && !reader.IsDBNull(colIdx))
                            {
                                props[i].SetValue(item, reader[colIdx]);
                            }
                        }

                        baseTable.AddObject(item);
                    }
                }
            }
        }
Example #20
0
 /// <summary>
 /// Validates that the primary key exists.
 /// </summary>
 private bool PkExists(IBaseTable parentTable, int key, string childColumn, out string errMsg)
 {
     if (parentTable.PkExists(key))
     {
         errMsg = "";
         return(true);
     }
     else
     {
         errMsg = string.Format(AppPhrases.DataNotExist, dataGridView.Columns[childColumn].HeaderText);
         return(false);
     }
 }
Example #21
0
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public FrmEntitySelect(IBaseTable baseTable)
            : this()
        {
            this.baseTable = baseTable ?? throw new ArgumentNullException(nameof(baseTable));
            items          = null;
            selectedItems  = null;

            MultiSelect   = true;
            SelectedIDs   = null;
            SelectedID    = 0;
            SelectedItems = null;
            SelectedItem  = null;
        }
Example #22
0
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public FrmBaseTable(IBaseTable baseTable, TableFilter tableFilter, ScadaProject project, AppData appData)
            : this()
        {
            this.baseTable   = baseTable ?? throw new ArgumentNullException("baseTable");
            this.tableFilter = tableFilter;
            this.project     = project ?? throw new ArgumentNullException("project");
            this.appData     = appData ?? throw new ArgumentNullException("appData");

            dataTable = null;
            maxRowID  = 0;
            frmFind   = null;

            Text = baseTable.Title + (tableFilter == null ? "" : " - " + tableFilter);
        }
Example #23
0
        /// <summary>
        /// Gets a new table from the source table filtered by objects.
        /// </summary>
        private static IBaseTable GetFilteredTable <T>(IBaseTable srcTable, List <int> objNums)
        {
            IBaseTable destTable = new BaseTable <T>(srcTable.PrimaryKey, srcTable.Title);

            foreach (int objNum in objNums)
            {
                foreach (object item in srcTable.SelectItems(new TableFilter("ObjNum", objNum), true))
                {
                    destTable.AddObject(item);
                }
            }

            return(destTable);
        }
 /// <summary>
 /// Reads the table of the configuration database.
 /// </summary>
 public override void ReadBaseTable(IBaseTable baseTable)
 {
     try
     {
         Monitor.Enter(conn);
         conn.Open();
         PostgreSqlStorageShared.ReadBaseTable(baseTable, conn);
     }
     finally
     {
         conn.Close();
         Monitor.Exit(conn);
     }
 }
Example #25
0
 /// <summary>
 /// Exports the table.
 /// </summary>
 private bool Export(IBaseTable baseTable, BaseTableFormat format)
 {
     try
     {
         new ImportExport().ExportBaseTable(saveFileDialog.FileName, format, baseTable,
                                            chkStartID.Checked ? Convert.ToInt32(numStartID.Value) : 0,
                                            chkEndID.Checked ? Convert.ToInt32(numEndID.Value) : int.MaxValue);
         return(true);
     }
     catch (Exception ex)
     {
         appData.ProcError(ex, string.Format(AdminPhrases.ExportBaseTableError, baseTable.Name));
         return(false);
     }
 }
Example #26
0
        /// <summary>
        /// Creates a data table for using as a data source of a combo box.
        /// </summary>
        private DataTable CreateComboBoxSource(
            IBaseTable baseTable, string valueMember, string displayMember, bool addEmptyRow)
        {
            DataTable dataTable = baseTable.ToDataTable(true);

            if (addEmptyRow)
            {
                DataRow emptyRow = dataTable.NewRow();
                emptyRow[valueMember]   = DBNull.Value;
                emptyRow[displayMember] = " ";
                dataTable.Rows.Add(emptyRow);
            }

            dataTable.DefaultView.Sort = displayMember;
            return(dataTable);
        }
Example #27
0
 /// <summary>
 /// Saves the specified table of the configuration database.
 /// </summary>
 public bool SaveTable(IBaseTable baseTable, out string errMsg)
 {
     try
     {
         Directory.CreateDirectory(BaseDir);
         string fileName = Path.Combine(BaseDir, baseTable.FileName);
         baseTable.Save(fileName);
         errMsg = "";
         return(true);
     }
     catch (Exception ex)
     {
         errMsg = string.Format(AdminPhrases.SaveBaseTableError, baseTable.Title) + ":" + ex.Message;
         return(false);
     }
 }
Example #28
0
 /// <summary>
 /// Saves the specified table of the configuration database.
 /// </summary>
 public bool SaveTable(IBaseTable baseTable, out string errMsg)
 {
     try
     {
         Directory.CreateDirectory(BaseDir);
         string fileName = Path.Combine(BaseDir, baseTable.FileName);
         baseTable.Save(fileName);
         errMsg = "";
         return(true);
     }
     catch (Exception ex)
     {
         errMsg = ScadaUtils.BuildErrorMessage(ex, AdminPhrases.SaveBaseTableError, baseTable.Title);
         return(false);
     }
 }
Example #29
0
        /// <summary>
        /// Gets the output file name.
        /// </summary>
        private string GetOutputFileName(IBaseTable baseTable, out BaseTableFormat format)
        {
            switch (cbFormat.SelectedIndex)
            {
            case 0:
                format = BaseTableFormat.DAT;
                return(baseTable.Name.ToLowerInvariant() + ".dat");

            case 1:
                format = BaseTableFormat.XML;
                return(baseTable.Name + ".xml");

            default:
                format = BaseTableFormat.CSV;
                return(baseTable.Name + ".csv");
            }
        }
Example #30
0
        /// <summary>
        /// Copies the changes from the DataTable to the BaseTable.
        /// </summary>
        public static void RetrieveChanges(this IBaseTable baseTable, DataTable dataTable)
        {
            // delete rows from the target table
            DataRow[] deletedRows = dataTable.Select("", "", DataViewRowState.Deleted);

            foreach (DataRow row in deletedRows)
            {
                int key = (int)row[baseTable.PrimaryKey, DataRowVersion.Original];
                baseTable.RemoveItem(key);
                row.AcceptChanges();
            }

            // change rows in the target table
            Type itemType = baseTable.ItemType;
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(itemType);

            DataRow[] modifiedRows = dataTable.Select("", "", DataViewRowState.ModifiedCurrent);

            foreach (DataRow row in modifiedRows)
            {
                object item    = CreateItem(itemType, row, props);
                int    origKey = (int)row[baseTable.PrimaryKey, DataRowVersion.Original];
                int    curKey  = (int)row[baseTable.PrimaryKey, DataRowVersion.Current];

                if (origKey != curKey)
                {
                    baseTable.RemoveItem(origKey);
                }

                baseTable.AddObject(item);
                row.AcceptChanges();
            }

            // add rows to the target table
            DataRow[] addedRows = dataTable.Select("", "", DataViewRowState.Added);

            foreach (DataRow row in addedRows)
            {
                object item = CreateItem(itemType, row, props);
                baseTable.AddObject(item);
                row.AcceptChanges();
            }
        }