Таблица имеет значение NULL DateTime, но DataSet генерирует исключение?
Я пытаюсь использовать конструктор DataSet для создания datatable из запроса. Я все понял. Используемый запрос возвращает столбец с нулевым столбцом datetime из базы данных. Но, когда он обходит этот код:
DataSet1.DataTable1DataTable table = adapter.GetData();
Это вызывает исключение StrongTypingException:
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public System.DateTime event_start_date {
get {
try {
return ((global::System.DateTime)(this[this.tableDataTable1.event_start_dateColumn]));
}
catch (global::System.InvalidCastException e) {
throw new global::System.Data.StrongTypingException("The value for column \'event_start_date\' in table \'DataTable1\' is DBNull.", e);
}
}
set {
this[this.tableDataTable1.event_start_dateColumn] = value;
}
}
Как использовать конструктор, чтобы этот столбец был Nullable?
Ответы
Ответ 1
Типизированные наборы данных не поддерживают типы с нулевым значением. Они поддерживают столбцы с нулевым значением.
Генератор типизированных наборов данных создает свойства, не допускающие нулевых значений, и связанные методы для обработки нулевых значений. Если вы создадите столбец MyDate
типа DateTime
и AllowDbNull
, установленный в true
, подкласс DataRow
будет реализовывать свойство с нулевым значением DateTime
с именем MyDate
, a SetMyDateNull()
и a IsMyDateNull()
. Это означает, что если вы хотите использовать в своем коде тип с нулевым значением, вы должны сделать это:
DateTime? myDateTime = myRow.IsMyDateNull() ? null : (DateTime?) row.MyDate;
Хотя это не полностью разрушает цель использования типизированных наборов данных, это действительно отстой. Это расстраивает то, что типизированные наборы данных реализуют столбцы с нулевым значением, например, менее используемые, чем методы расширения System.Data
.
Особенно плохо, потому что типизированные наборы данных в некоторых местах используют типы с нулевым значением - например, метод Add<TableName>Row()
для таблицы, содержащей столбец столбца DateTime с нулевыми значениями, описанный выше, будет иметь параметр DateTime?
.
Недавно я спросил об этой проблеме на форумах MSDN, и в конечном итоге менеджер проекта ADO объяснил, что типы с нулевым значением были реализованы одновременно с типизированными наборами данных, и его команда не успела полностью интегрировать эти два по дате отправки .NET 2.0. И насколько я могу судить, они не добавили новых функций для типизированных наборов данных с тех пор.
Ответ 2
Кажется, что Designer
получил неверный тип базы данных для столбца.
Откройте xsd Designer
, нажмите F4
, чтобы открыть Properties Window
. Выберите соответствующий столбец и установите для параметра Nullable
(или что-то подобное, не помните точное имя) значение true.
Ответ 3
Спасибо, это решило мою аналогичную проблему: вот код.
В случае возникновения этого вопроса
Isevent_start_date()
вернет, будет ли поле нулевым.
В моем случае: у меня была аналогичная проблема, и я использовал следующее решение
//Table Name is Efforts,
//Column name is Target
//So the dataset would automatically generate a property called IsTargetNull() which can be used to check nullables
//Create an Adaptor
EffortsTableAdapter ad = new EffortsTableAdapter();
ProjectDashBoard.Db.EffortsDataTable efforts = ad.GetData();
DataColumn targetColumn = new DataColumn();
targetColumn = efforts.TargetColumn;
List<DateTime?> targetTime = new List<DateTime?>();
foreach (var item in efforts)
{
//----------------------------------------------------
//This is the line that we are discussing about :
DateTime? myDateTime = item.IsTargetNull() ? null : (DateTime?)item.Target;
//----------------------------------------------------
targetTime.Add(myDateTime);
}
Ответ 4
Чтобы сделать эту работу с LINQ, вам нужно перейти к свойствам таблиц в вашем файле dataset.xsd. Сначала посмотрите и убедитесь, что столбец действительно установлен в значение NULL. Затем вы должны посмотреть конкретное свойство "NullValue" для столбца. Значение Null по умолчанию равно "Исключение", по крайней мере, в VS 2012. Установите для него значение Nothing для VB, чтобы вы могли "IsNot Nothing" в предложении LINQ Where.
Ответ 5
Я сделал это, чтобы вставить значение NULL
в столбец DateTime
,
Предполагая, что у меня есть столбец nullable DateTime
с nullable DateTime
в базе данных, я получил некоторые данные из базы данных в объекте с именем response
и я хочу вставить nullable DateTime
с RenewDate
значением в столбец DataSet, который называется RenewDate
:
// create anew row of the same type of your table row
var rw = ds.StudentActionPrintDT.NewStudentActionPrintDTRow();
// check for null value
if(!response.RenewDate.HasValue)
{
// if null, then the let DataSet to set it null by it own way
rw.SetRenewDateNull();
}
else
{
// if not null set value to the datetime value
rw.RenewDate = response.RenewDate.Value;
}
// add the created row to the dateset [DataSetName].[ColumnName].Add[ColumnName]Row([The Created Row]);
ds.StudentActionPrintDT.AddStudentActionPrintDTRow(rw);
Ответ 6
Я использую приведенный ниже код для обработки нулевых ячеек на листе Excel, который читается в datatable.
if (!reader.IsDBNull(0))
{
row["DateOnCall"] = (DateTime)reader[0];
}
Ответ 7
Кажется, отличается от DataTable и сильно типизированного DataTable... Используйте как это.
DataSet1.DataTable1DataTable table = new DataSet1.DataTable1DataTable();
table.Merge(adapter.GetData().CopyToDataTable());
Ответ 8
В DataSet Designer используйте тип данных System.Object
вместо System.DateTime
и задайте для NullValue значение (Null)
а для DefaultValue - значение <DBNull>
и, когда это необходимо, преобразуйте его, например:
var row1 = dateSet1.table1.FirstOrDefault();
if (row1 == null)
return;
DateTime? date = (DateTime?) row1.ObjectDate;
Ответ 9
Объект System.DateTime не имеет значения NULL. Чтобы присвоить значение DateTime nullable, установите DateTime? (поместите a? после DateTime)
DateTime? nullableDateTime = null;