Абстрактные методы - это те, которые вы должны определить, когда вы наследуете эту ABC.
В столбце Mixin перечислены методы, которые вы можете использовать впоследствии, вы получаете их бесплатно, наследуя не от object
, но от этой ABC. Если вы определяете __getitem__
, вы можете автоматически использовать __iter__
впоследствии, например.
Еще одно преимущество наследования от этих классов - это то, что каждый может видеть после этого, каким должен был быть ваш класс, поскольку он issubclass(your_class, any_ABC)
, а любой экземпляр - isinstance(your_object, any_ABC)
. Но это написано в учебнике после таблицы, которую вы опубликовали.
Вы не можете изменить DataType
DataColumn
после заполнения его данными. Это свойство не только для чтения, но вы получите исключение во время выполнения, если попытаетесь изменить его после того, как у него уже есть данные.
Исключение создается при изменении этого свойства после того, как столбец начал хранить данные.
Таким образом, вам нужно будет либо обеспечить правильные типы столбцов в начале (если возможно), либо создать новую DataTable
специально для импорта и копирования данных из исходной DataTable
.
Вы также можете написать собственный класс IDataReader
, который читает из вашего DataTable
, выполняет своевременное преобразование и передает его в SqlBulkCopy
- it было бы намного эффективнее, но это, очевидно, не быстрое решение.
Я создал улучшенную версию Gisway / Yuri Galanter решение, которое обращается к следующим моментам:
AllowDBNull
из первоначального столбца Как проект, в котором я нуждался, это для находится в VB.Net, мое решение записано (и протестировано) в нем также, извините - преобразование не должно быть трудным все же.
' following methods will be defined in a module, which is why they aren't Shared
' based on https://codecorner.galanter.net/2013/08/02/ado-net-datatable-change-column-datatype-after-table-is-populated-with-data/
' and https://stackoverflow.com/a/15692087/1200847
''' <summary>
''' Converts DataType of a DataTable's column to a new type by creating a copy of the column with the new type and removing the old one.
''' </summary>
''' <param name="table">DataTable containing the column</param>
''' <param name="columnName">Name of the column</param>
''' <param name="newType">New type of the column</param>
<Extension()>
Public Sub ChangeColumnDataType(table As DataTable, columnName As String, newType As Type)
If Not table.Columns.Contains(columnName) Then Throw New ArgumentException($"No column of the given table is named ""{columnName}"".")
Dim oldCol As DataColumn = table.Columns(columnName)
oldCol.ChangeDataType(newType)
End Sub
''' <summary>
''' Converts DataType of a DataTable's column to a new type by creating a copy of the column with the new type and removing the old one.
''' </summary>
''' <param name="column">The column whichs type should be changed</param>
''' <param name="newType">New type of the column</param>
<Extension()>
Public Sub ChangeDataType(column As DataColumn, newType As Type)
Dim table = column.Table
If column.DataType Is newType Then Return
Dim tempColName = "temporary-327b8efdb7984e4d82d514230b92a137"
Dim newCol As New DataColumn(tempColName, newType)
newCol.AllowDBNull = column.AllowDBNull
table.Columns.Add(newCol)
newCol.SetOrdinal(table.Columns.IndexOf(column))
For Each row As DataRow In table.Rows
row(tempColName) = Convert.ChangeType(row(column), newType)
Next
table.Columns.Remove(column)
newCol.ColumnName = column.ColumnName
End Sub
, Если Вы т.е. имеете int
столбец, который действительно должен быть bool
столбец, используйте его как это:
table.Columns("TrueOrFalse").ChangeDataType(GetType(Boolean))
Важный : Поскольку это изменяет DataTable, Вы возможный хотите сделать это правильно после загрузки данных и принять изменения впоследствии. Таким образом, отслеживание изменений, связывая с данными и т.д. работает обычно впоследствии:
table.AcceptChanges()
<час> , Если non-nullability Вашего столбца не настроен правильно при загрузке данных, поскольку это имело место для моего столбца Oracle NUMBER(1,0) NOT NULL
, можно хотеть ввести код как это:
table.Columns("TrueOrFalse").AllowDBNull = False
table.Columns("TrueOrFalse").DefaultValue = 0
Обязательно установите типы данных для заполняемой вами таблицы данных.
Например:
DataTable table = new DataTable("countries");
table.Columns.Add("country_code", typeof (string));
table.Columns.Add("country_name", typeof (string));
//...
//Fill table
Или вы можете изменить типы столбцов, если они совместимы:
table.Columns["country_code"].DataType = typeof(string);