Таблица обнуляется DateTime, но DataSet выдает исключение? - PullRequest
20 голосов
/ 28 октября 2009

Я пытаюсь использовать конструктор DataSet для создания данных из запроса. Я поняла это просто отлично. Используемый запрос возвращает обнуляемый столбец даты и времени из базы данных. Но когда доходит до этого кода:

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;
    }
}

Как использовать конструктор, чтобы этот столбец можно было обнулять?

Ответы [ 9 ]

41 голосов
/ 28 октября 2009

Типизированные наборы данных не поддерживают обнуляемые типы. Они поддерживают Nullable столбцы .

Генератор набора типизированных данных создает ненулевые свойства и связанные методы для обработки нулевых значений. Если вы создаете столбец MyDate типа DateTime и AllowDbNull, установленный на true, подкласс DataRow будет реализовывать свойство DateTime, не допускающее обнуление, с именем MyDate, метод SetMyDateNull() и IsMyDateNull() метод. Это означает, что если вы хотите использовать в своем коде обнуляемый тип, вы должны сделать это:

DateTime? myDateTime = myRow.IsMyDateNull() ? null : (DateTime?) row.MyDate;

Хотя это не полностью не лишает цели использования типизированных наборов данных, это действительно отстой. Обидно, что типизированные наборы данных реализуют пустые столбцы таким образом, что они менее удобны, чем, например, методы расширения System.Data.

Особенно плохо, потому что типизированные наборы данных do в некоторых местах используют обнуляемые типы - например, метод Add<TableName>Row() для таблицы, содержащей столбец DateTime со значением NULL, описанный выше, примет параметр DateTime?.

Давным-давно я спрашивал об этой проблеме на форумах MSDN, и в конечном итоге менеджер проекта ADO объяснил, что типы nullable были реализованы одновременно с типизированными наборами данных, и его команда не успела полностью объединить эти два элемента. к дате поставки .NET 2.0. И, насколько я могу судить, с тех пор они не добавляли новые функции в наборы типизированных данных.

1 голос
/ 21 марта 2018

Я сделал это, чтобы вставить значение NULL в столбец DateTime,

предполагая, что у меня есть столбец nullable DateTime в базе данных, я извлек некоторые данные из базы данных в объект с именем response и хочу вставить значение nullable DateTime в столбец 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's 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);
1 голос
/ 26 марта 2013

Для работы с LINQ вам нужно перейти к свойствам таблиц в вашем dataset.xsd. Сначала посмотрите и убедитесь, что столбец действительно имеет значение nullable. ТОГДА вы должны посмотреть на конкретное свойство "NullValue" для столбца. По умолчанию для Null Value установлено значение «Exception», по крайней мере, в VS 2012. Установите для него значение Nothing для VB, чтобы в предложении LINQ Where можно было выполнить «IsNot Nothing».

1 голос
/ 31 июля 2012

Спасибо, это решило мою похожую проблему: вот код.В случае этого вопроса

Isevent_start_date()

вернет, будет ли поле пустым.

В моем случае: у меня была похожая проблема, и я использовал следующее решение

            //Table's Name is Efforts,
            //Column's 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);

            }
1 голос
/ 28 октября 2009

Кажется, Designer неверно указал тип базы данных для столбца.

Откройте xsd Designer, нажмите F4, чтобы открыть Properties Window. Выберите соответствующий столбец и установите Nullable (или что-то в этом роде, не помните точное имя) в true.

0 голосов
/ 29 апреля 2019

В DataSet Designer используйте System.Object тип данных вместо System.DateTime и установите NullValue на (Null) и DefaultValue на <DBNull> и, когда это необходимо, преобразуйте его, например:

var row1 = dateSet1.table1.FirstOrDefault();
if (row1 == null)
    return;
DateTime? date = (DateTime?) row1.ObjectDate;
0 голосов
/ 13 июня 2016

С DataTable и DataTable со строгим типом данных все выглядит иначе ...

DataSet1.DataTable1DataTable table = new DataSet1.DataTable1DataTable();
table.Merge(adapter.GetData().CopyToDataTable());
0 голосов
/ 02 ноября 2012

Я использую приведенный ниже код для обработки пустых ячеек на листе Excel, который считывается в таблицу данных.

if (!reader.IsDBNull(0))                                
{                                    
  row["DateOnCall"] = (DateTime)reader[0];
}
0 голосов
/ 28 октября 2009

Объект System.DateTime не обнуляется. Чтобы сделать DateTime обнуляемым сделать его DateTime? (поставить? после DateTime)

DateTime? nullableDateTime = null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...