コード例 #1
0
ファイル: DataSetUtil.cs プロジェクト: Fredo-Q/dotnet-corefx
    static internal ArgumentOutOfRangeException InvalidDataRowState(DataRowState value)
    {
#if DEBUG
        switch (value)
        {
        case DataRowState.Detached:
        case DataRowState.Unchanged:
        case DataRowState.Added:
        case DataRowState.Deleted:
        case DataRowState.Modified:
            Debug.Fail("valid DataRowState " + value.ToString());
            break;
        }
#endif
        return(InvalidEnumerationValue(typeof(DataRowState), (int)value));
    }
コード例 #2
0
        public static void SerializeDataTable(BinaryWriter bw, DataTable dt)
        {
            DataColumnCollection columns = dt.Columns;
            int iColCount = columns.Count;

            TypeCode[] colTypeCodes = new TypeCode[iColCount];

            bool[] aryIsNullabl = new bool[iColCount];

            // Имя таблицы
            bw.Write(dt.TableName);

            bw.Write(iColCount);
            // Получаем и записываем описание колонок.
            for (int i = 0; i < iColCount; i++)
            {
                DataColumn dc = columns[i];
                // Получаем TypeCode для типа обрабатываемой колонки.
                TypeCode tc = Type.GetTypeCode(dc.DataType);
                // Запоминаем TypeCode колонки в соотвествующем массиве.
                colTypeCodes[i] = tc;
                bw.Write(dc.ColumnName);
                // Записываем TypeCode как Int32. Можно было бы и
                // сэкономить 3 байта. :)
                bw.Write((Int32)tc);

                // Создаем массив информации о поддержке колонками DBNull
                aryIsNullabl[i] = dc.AllowDBNull;
            }


            // Записываем битовое поле описывающее колонки поддерживающие
            // DBNull. Если бит поднят, значит, колонка поддерживает DBNull.
            BitArray bitsNull = new BitArray(aryIsNullabl);

            byte[] byteNull = new byte[(iColCount + 7) / 8];
            bitsNull.CopyTo(byteNull, 0);
            bw.Write(byteNull);

            ///////////////////////////////////////////////////////////////
            // add data

            // count rows
            bw.Write(dt.Rows.Count);

            // Записываем строки
            foreach (DataRow dr in dt.Rows)
            {
                byte verFlags = 0;
                int  iVerStart;
                int  iVerEnd;
                // Разбираемся, какие версии нужно писать.
                // Всего есть два варианта: Original и Current
                DataRowState state = dr.RowState;
                switch (state)
                {
                // Original + Current и они равны!
                case DataRowState.Unchanged:
                    iVerStart = 0;
                    iVerEnd   = 0;
                    verFlags  = 0;
                    break;

                case DataRowState.Deleted:                         // Только Original
                    iVerStart = 0;
                    iVerEnd   = 0;
                    verFlags  = 1;
                    break;

                case DataRowState.Added:                         // Только Current
                    iVerStart = 1;
                    iVerEnd   = 1;
                    verFlags  = 2;
                    break;

                // Original + Current и они НЕ равны!
                case DataRowState.Modified:
                    iVerStart = 0;
                    iVerEnd   = 1;
                    verFlags  = 3;
                    break;

                default:
                    throw new ApplicationException(
                              "Недопустимое состояние строки: " + state.ToString());
                }

                // Пишем описание версий. Временно, так как на этом мы
                // теряем байт на строку. Куда лучше писать дополнительные два
                // бита в битовое поле DbNull (хотя это и не красиво).
                bw.Write(verFlags);

                // Записываем версии текущей строки. Всего их может быть две.
                // в принципе можно было бы для случая DataRowState.Modified
                // писать только дельту данных. Но это как-нибудь потом. :)
                for (int iVetIndex = iVerStart; iVetIndex <= iVerEnd; iVetIndex++)
                {
                    DataRowVersion drv = _aryVer[iVetIndex];

                    // Создаем и заполняем битовое поле. Если бит поднят,
                    // значит, соответствующая колонка содержит DBNull.
                    bitsNull.SetAll(false);
                    for (int i = 0; i < iColCount; i++)
                    {
                        if (dr[i, drv] == DBNull.Value)
                        {
                            bitsNull.Set(i, true);
                        }
                    }
                    bitsNull.CopyTo(byteNull, 0);
                    // Записываем битовое поле в стрим.
                    bw.Write(byteNull);

                    // Перебираем колонки и пишем данные...
                    for (int i = 0; i < iColCount; i++)
                    {
                        // Если колонка содержит DBNull, записывать ее значение
                        // ненужно.
                        object data = dr[i, drv];
                        if (data == DBNull.Value)                        // Учитываем версию!
                        {
                            continue;
                        }

                        // Записываем данные ячейки.
                        switch (colTypeCodes[i])
                        {                               // Каждому типу соответствует переопределенная функция...
                        case TypeCode.Boolean: bw.Write((Boolean)data); break;

                        case TypeCode.Char: bw.Write((Char)data); break;

                        case TypeCode.SByte: bw.Write((SByte)data); break;

                        case TypeCode.Byte: bw.Write((Byte)data); break;

                        case TypeCode.Int16: bw.Write((Int16)data); break;

                        case TypeCode.UInt16: bw.Write((UInt16)data); break;

                        case TypeCode.Int32: bw.Write((Int32)data); break;

                        case TypeCode.UInt32: bw.Write((UInt32)data); break;

                        case TypeCode.Int64: bw.Write((Int64)data); break;

                        case TypeCode.UInt64: bw.Write((UInt64)data); break;

                        case TypeCode.Single: bw.Write((Single)data); break;

                        case TypeCode.Double: bw.Write((Double)data); break;

                        case TypeCode.Decimal: bw.Write((Decimal)data); break;

                        case TypeCode.DateTime:
                            // Для DateTime приходится выпендриваться особым образом.
                            bw.Write(((DateTime)(data)).ToFileTime());
                            break;

                        case TypeCode.String: bw.Write((String)data); break;

                        default:
                            // На всякий случай пробуем записать неопознанный тип
                            // виде строки.
                            bw.Write(data.ToString());
                            break;
                        }
                    }
                }
            }
        }