проблема преобразования с нулевым значением DateTime в запросе LINQ - PullRequest
0 голосов
/ 06 марта 2012

Вот конфигурация моих таблиц данных, которые я использую в своем запросе linq: У меня есть 2 файла набора данных (во всех столбцах всех таблиц указан DataType и их свойство AllowDbNull установлено в True): * deposit_position_imbalance.xsd: Содержит 2 данных: - Дисбаланс - ImbalanceDetailForRealTime * dep_pos_imbalance_detail.xsd: Содержит 1 данные: - Таблица

В приведенном ниже коде проблема заключается в 2 строках "deal_date = b.deal_date". Действительно, когда я извлекаю из базы данных b.deal_date со значением NULL, он говорит в deposit_position_imbalance.Designer.cs: «StrongTypingException не был обработан кодом пользователя» «Значение столбца deal_date в таблице« ImbalanceDetailForRealTime »равно DBNull.» Msgstr "Указанный состав недействителен". Вот где выдает ошибку:


    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
            public System.DateTime deal_date {
                get {
                    try {
                        return ((global::System.DateTime)(this[this.tableImbalanceDetailForRealTime.deal_dateColumn]));
                    }
                    catch (global::System.InvalidCastException e) {
                        throw new global::System.Data.StrongTypingException("The value for column \'deal_date\' in table \'ImbalanceDetailForRealTime\' is DBNull." +
                                "", e);//ERROR THROWN HERE
                    }
                }
                set {
                    this[this.tableImbalanceDetailForRealTime.deal_dateColumn] = value;
                }
            }
  • Я попытался заменить строку "deal_date = b.deal_date" на "deal_date = (DateTime?) b.deal_date" Но я получаю 2 ошибки компиляции: «Лучший перегруженный метод соответствует для dep_pos_imbalance_detail.TableDataTable.AddTableRow (string, System.DateTime) 'имеет недопустимые аргументы» и "Аргумент" 2 ": невозможно преобразовать из" System.DateTime? " в "System.DateTime" "
  • Я также попытался заменить строку "deal_date = b.deal_date" на "deal_date = b.deal_date == null? (DateTime) DBNull.Value: b.deal_date" Но я получаю ошибку компиляции: «Не удается преобразовать тип« System.DBNull »в System.DateTime» »
  • Затем я попытался заменить строку "deal_date = b.deal_date" на "deal_date = b.deal_date == null? (DateTime?) DBNull.Value: b.deal_date" Но я получаю ошибку компиляции: «Не удается преобразовать тип« System.DBNull »в System.DateTime?» »
  • Я пробовал еще одну вещь: заменить "deal_date = b.deal_date" на "deal_date = b.Isdeal_dateNull ()? default (DateTime?): b.deal_date" Но опять же, у меня есть следующие ошибки: «Наилучшее совпадение перегруженного метода для dep_pos_imbalance_detail.TableDataTable.AddTableRow (string, System.DateTime) 'имеет недопустимые аргументы» и "Аргумент" 2 ": невозможно преобразовать из" System.DateTime? " в «System.DateTime» На следующем изображении (извините, мне пока не разрешено вставлять изображение в stackoverflow, поэтому я поместил ссылку вместо него) показано определение моего столбца deal_date в моем наборе данных: https://lh5.googleusercontent.com/-TEZZ9Hdnkl4/T1aRxF_i7II/AAAAAAAAAAg/BwzrVXIlOHE/s323/deal_date.jpg Мы видим, что у меня нет возможности установить "System.DateTime?" но только "System.DateTime". И я не хочу ничего, кроме нуля, в качестве значения по умолчанию (нужно ли ставить что-то другое, чем значение по умолчанию "", чтобы оно работало?) ОБНОВЛЕНИЕ -> Я попытался поставить ноль вместо, и разработчик выдает эту ошибку: «Строка не была распознана как допустимый DateTime. Есть неизвестное слово, начинающееся с индекса 0.».

Так что я не понимаю, как мне удается получить нулевые значения (я не вставил это в код, но у меня та же проблема с типом double). У меня такое впечатление, что мои столбцы настроены на включение нулевых значений, но, очевидно, нет ... Кроме того, когда я пытаюсь изменить свойство NullValue, чтобы перейти от «(Throw Exception)» к «(Empty)» или «(Null)», конструктор выдает следующую ошибку: «Введенное значение недопустимо для текущего типа данных «. Спасибо за помощь. Вот мой запрос LINQ:

deposit_position_imbalance.ImbalanceDataTable dtImbalanceForRealTime;
deposit_position_imbalance.ImbalanceDetailForRealTimeDataTable dtImbalanceDetailForRealTime;

dtImbalanceForRealTime = (deposit_position_imbalance.ImbalanceDataTable)(((deposit_position_imbalance)(dataManager.GetConfig(grid1).ParentDataSource)).Imbalance);
dtImbalanceDetailForRealTime = this.detailForRealTime;

// we separate security_id null and not null
// Security id is not null
deposit_position_imbalance.ImbalanceDataTable iWithSecurityIdNotNull = new deposit_position_imbalance.ImbalanceDataTable();
deposit_position_imbalance.ImbalanceRow[] dr1 = (deposit_position_imbalance.ImbalanceRow[])dtImbalanceForRealTime.Select("security_id is not null");
if (dr1.Count<deposit_position_imbalance.ImbalanceRow>() > 0)
{
    DataTable looselyTypedDT1 = dr1.CopyToDataTable<deposit_position_imbalance.ImbalanceRow>();
    iWithSecurityIdNotNull.Merge(looselyTypedDT1, true);
}

// Security id is null
deposit_position_imbalance.ImbalanceDataTable iWithSecurityIdNull = new deposit_position_imbalance.ImbalanceDataTable();
deposit_position_imbalance.ImbalanceRow[] dr2 = (deposit_position_imbalance.ImbalanceRow[])dtImbalanceForRealTime.Select("security_id is null");
if (dr2.Count<deposit_position_imbalance.ImbalanceRow>() > 0)
{
    DataTable looselyTypedDT2 = dr2.CopyToDataTable<deposit_position_imbalance.ImbalanceRow>();
    iWithSecurityIdNull.Merge(looselyTypedDT2, true);
}

var queryWithSecurityIdFound =
    from a in iWithSecurityIdNotNull
    join b in dtImbalanceDetailForRealTime
    on new
    {
        a.situation_date,
        a.security_id,
        a.deposit_location_id,
        a.account_keeper_id
    }
        equals new
        {
            b.situation_date,
            b.security_id,
            b.deposit_location_id,
            b.account_keeper_id
        }
    where a.situation_date == situation_date
       && a.security_id == security_id
       && a.deposit_location_id == deposit_location_id
       && a.account_keeper_id == account_keeper_id
    select new
    {
        name = a.bo_source_name,
        deal_date = b.deal_date
    };

var queryWithSecurityIdNotFound =
    from a in iWithSecurityIdNull
    join b in dtImbalanceDetailForRealTime
        on new
        {
            a.situation_date,
            a.security_code,
            a.deposit_location_id,
            a.account_keeper_id
        }
        equals new
        {
            b.situation_date,
            b.security_code,
            b.deposit_location_id,
            b.account_keeper_id
        }
    where a.situation_date == situation_date
       && a.security_id == security_id
       && a.deposit_location_id == deposit_location_id
       && a.account_keeper_id == account_keeper_id
    select new
    {
        name = a.bo_source_name,
        deal_date = b.deal_date
    };

var query_final = queryWithSecurityIdFound.Union(queryWithSecurityIdNotFound);
//We fill the 'dep_pos_imbalance_detail Table'
grid1.Clear();
foreach (var item in query_final)
{
    ((dep_pos_imbalance_detail.TableDataTable)grid1.DataSet.Tables["Table"]).AddTableRow(item.name, item.deal_date);
}

Ответы [ 2 ]

1 голос
/ 06 марта 2012

Если это strongly typed DataSet, он автоматически генерирует свойства для пустых столбцов, таких как Isdeal_dateNull, которые вы должны использовать вместо.

if (!row.Isdeal_dateNull)
{
   //do something
}
0 голосов
/ 09 марта 2012

Я нашел способ решить мою проблему.В моих запросах LINQ я заменяю "deal_date = b.deal_date" на "deal_date = b.Field ('deal_date')".Преобразование может быть сделано.Затем я не могу использовать автоматически сгенерированный в Designer метод AddTableRow, потому что он не ожидает правильных типов.Но я пишу это немного дольше, но эффективно:

dep_pos_imbalance_detail.TableDataTable dt = ((dep_pos_imbalance_detail.TableDataTable)grid1.DataSet.Tables["Table"]);
dep_pos_imbalance_detail.TableRow dr = dt.NewTableRow();
foreach (var item in query_final)
{
   dr = dt.NewTableRow();
   dr.name = item.name;
   if (item.deal_date.HasValue)
       dr.deal_date = item.deal_date.Value;
   else
       dr.Setdeal_dateNull();
   dt.AddTableRow(dr);
}
...