DataTable "динамические" поле не работает
От: SeLo  
Дата: 30.04.15 14:14
Оценка:
Привет, имею следующую проблему с типизированной таблицей DataTable:
Созданную таблицу расширяю своим методом который инициализирует новую колонку. Колонка должна содержать вычисляемые данные, но *не* является express колонкой (eсть причины)

Так вот, во время выполнения Merge таблиц или MyTable.ImportRow(...) вываливаетя исключение ArgumentException (ожидался тип String) на помеченной строке ниже, но после F5 программа продолжает работать и без catch не прерывается.
Правда значение колонки остается пустым.
Что я не так делаю?

public partial class MyDataTable
        {
            private global::System.Data.DataColumn columnMyRowDisplay;
            public global::System.Data.DataColumn MyRowDisplayColumn {
                get {
                    return this.columnMyRowDisplay;
                }
            }

            public void InitMyRowDisplay() {
                if (columnMyRowDisplay != null) return;

                columnMyRowDisplay = new DataColumn("MyRowDisplay", typeof(String));
                base.Columns.Add(columnMyRowDisplay);

                this.ColumnChanged += (sender, ea) => {
                    if ((ea.Column == this.Column1) || (ea.Column == this.Column2)) 
                        BuildAndSetMyRowDisplayValue(ea.Row);
                    
                };
                this.RowChanged += (sender, ea) => {
                    if (ea.Action == DataRowAction.Add) BuildAndSetMyRowDisplayValue(ea.Row); // !!! во время ImportRow входит здесь
                };
            }

             void BuildAndSetMyRowDisplayValue(DataRow row) {
                if (row == null) return;

                //if (row.Table.Columns.Contains("MyRowDisplay") == false) 
                //    return;
                

                // build
                String value = null;
                String value1 = row.Field<String>(this.Column1);
                String value2 = row.Field<String>(this.Column2);

                if ((String.IsNullOrEmpty(value1) == false) && (String.IsNullOrEmpty(value2) == false))
                    value = value2 + ", " + value1;
                else
                    value = String.Format("{0}{1}", value1, value2); 
                    
                // set
                row.SetField<String>(this.MyRowDisplayColumn, value); // value содержит значение, но вываливается исключение !!!!
                
            }
        }
        public partial class MyRow
        {
            public string MyRowDisplay {
                get {
                    return this.Field<String>(this.tableMy.MyRowDisplayColumn);
                }
                //set {
                //    this.SetField<String>(this.tableMy.MyRowDisplayColumn, value);
                //}
            }
        }
Re: DataTable "динамические" поле не работает
От: SeLo  
Дата: 04.05.15 08:56
Оценка:
Новая информация по ошибке:

Ошибка возникает здесь, на закоментированной строке. Если строка закоментированна, то ошибка не возникает.

dataSource = dataSet.Tables["MyTable"].AsEnumerable()
        .Where(x => String.IsNullOrEmpty(x.Field<String>("MyRowDisplay")) == false)
        //.OrderBy(x => x["MyRowDisplay"]) // !!!
    .AsDataView();


dataSource используется в DevExpress контроле LookUpEdit, но я не думаю, что это играет какую-то роль,

сообщение об ошибке "{"Das Objekt muss den Typ \"String\" haben."}", т.е. "Объект должен иметь тип String"


bei System.String.CompareTo(Object value)
bei System.Collections.Comparer.Compare(Object a, Object b)
bei System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
bei System.Data.EnumerableRowCollection`1.<>c__DisplayClass16`1.<AddSortExpression>b__15(Object val1, Object val2)
bei System.Data.SortExpressionBuilder`1.Compare(List`1 a, List`1 b)
bei System.Data.EnumerableRowCollection`1.<GetLinqDataView>b__4(DataRow a, DataRow b)
bei System.Data.Index.CompareDataRows(Int32 record1, Int32 record2)
bei System.Data.Index.CompareRecords(Int32 record1, Int32 record2)
bei System.Data.Index.IndexTree.CompareNode(Int32 record1, Int32 record2)
bei System.Data.RBTree`1.SearchSubTree(Int32 root_id, K key)
bei System.Data.RBTree`1.GetNodeByKey(K key)
bei System.Data.RBTree`1.GetIndexByKey(K key)
bei System.Data.Index.GetIndex(Int32 record, Int32 changeRecord)
bei System.Data.Index.RecordStateChanged(Int32 oldRecord, DataViewRowState oldOldState, DataViewRowState oldNewState, Int32 newRecord, DataViewRowState newOldState, DataViewRowState newNewState)
bei System.Data.DataTable.RecordStateChanged(Int32 record1, DataViewRowState oldState1, DataViewRowState newState1, Int32 record2, DataViewRowState oldState2, DataViewRowState newState2)
bei System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChanged, Int32 position, Boolean fireEvent, Exception& deferredException)
bei System.Data.DataTable.SetNewRecord(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean fireEvent, Boolean suppressEnsurePropertyChanged)
bei System.Data.DataRow.EndEdit()
bei System.Data.DataRow.set_Item(DataColumn column, Object value)
bei System.Data.DataRowExtensions.SetField[T](DataRow row, DataColumn column, T value)
// ...


Список нужен мне сортированным. Может кто-нибудь подсказать в чем проблема?
Re[2]: DataTable "динамические" поле не работает
От: SeLo  
Дата: 04.05.15 09:47
Оценка:
SL>
SL>dataSource = dataSet.Tables["MyTable"].AsEnumerable()
SL>        .Where(x => String.IsNullOrEmpty(x.Field<String>("MyRowDisplay")) == false)
SL>        //.OrderBy(x => x["MyRowDisplay"]) // !!!
SL>    .AsDataView();
SL>


Вылечил как показано ниже, но все равно, считаю, что исходный вариант тоже должен работать:
dataSource = dataSet.Tables["MyTable"].AsEnumerable()
        .Where(x => String.IsNullOrEmpty(x.Field<String>("MyRowDisplay")) == false)
        //.OrderBy(x => x["MyRowDisplay"]) // !!!
    .AsDataView();

dataSource.Sort = "MyRowDisplay";
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.