Что лучший способ состоит в том, чтобы иметь дело с DBNull's

Я использую Mongo 3.4.0

Оператор $ rename обновляет имя поля и имеет следующую форму:

{$rename: { : , : , ... } }

, например,

db.getCollection('user').update( { _id: 1 }, { $rename: { 'fname': 'FirstName', 'lname': 'LastName' } } )

Имя нового поля должно отличаться от имени существующего поля. Чтобы указать a во встроенном документе, используйте точечную нотацию.

Эта операция переименовывает поле nmae для имени для всех документов в коллекции:

db.getCollection('user').updateMany( {}, { $rename: { "add": "Address" } } )

db.getCollection('user').update({}, {$rename:{"name.first":"name.FirstName"}}, false, true);

В методе выше false, true: {upsert: false, multi: true}. Чтобы обновить все ваши записи, вам понадобится multi: true.

Переименуйте поле во встроенный документ

db.getCollection('user').update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )

используйте ссылку: https://docs.mongodb.com/manual/reference/operator/update/rename/

42
задан Mark 14 March 2016 в 09:58
поделиться

11 ответов

Типы Nullable хороши, но только для типов, которые не nullable для начала.

Для создания типа "nullable" добавляют вопросительный знак к типу, например:

int? value = 5;

я также рекомендовал бы использовать" as" ключевое слово вместо кастинга. Можно только использовать "в качестве" ключевого слова на nullable типах, поэтому удостоверьтесь, что Вы бросаете вещи, которые уже nullable (как строки), или Вы используете nullable типы, как упомянуто выше. Обоснование для этого

  1. , Если тип nullable," as" возвраты ключевого слова null, если значение DBNull.
  2. Это очень немного быстрее, чем кастинг хотя только в определенных случаях . Это самостоятельно никогда не достаточно хорошая причина использовать as, но вместе с причиной выше это полезно.

я рекомендовал бы делать что-то вроде этого

DataRow row = ds.Tables[0].Rows[0];
string value = row as string;

В случае выше, если row возвратится как DBNull, то value станет null вместо того, чтобы выдать исключение. Знайте, что, если Ваш запрос DB изменяет возвращаемые столбцы/типы, , использование as заставит Ваш код тихо приводить к сбою и делать значения простыми null вместо того, чтобы выдать соответствующее исключение, когда неправильные данные будут возвращены так, рекомендуется иметь в распоряжении тесты для проверки запросов другими способами гарантировать целостность данных, поскольку кодовая база развивается.

36
ответ дан Community 26 November 2019 в 23:37
поделиться

Если Вы обеспокоены получением DBNull при ожидании строк, одна опция состоит в том, чтобы преобразовать все значения DBNull в DataTable в пустую строку.

довольно просто сделать это, но это добавило бы немного служебные особенно, если Вы имеете дело с крупным DataTables. Проверьте этот ссылка , который показывает, как сделать это, если Вы заинтересованы

0
ответ дан Dejan 26 November 2019 в 23:37
поделиться

Brad Abrams отправил что-то связанное только несколько дней назад , http://blogs.msdn.com/brada/archive/2009/02/09/framework-design-guidelines-system-dbnull.aspx

, Таким образом, "Избегает использования Системы. DBNull. Предпочтите Nullable вместо этого".

И вот мои два цента (непротестированного кода :))

// Or if (row["fooColumn"] == DBNull.Value)
if (row.IsNull["fooColumn"])
{
   // use a null for strings and a Nullable for value types 
   // if it is a value type and null is invalid throw a 
   // InvalidOperationException here with some descriptive text. 
   // or dont check for null at all and let the cast exception below bubble  
   value = null;
}
else
{
   // do a direct cast here. dont use "as", "convert", "parse" or "tostring"
   // as all of these will swallow the case where is the incorect type.
   // (Unless it is a string in the DB and really do want to convert it)
   value = (string)row["fooColumn"];
}

И один вопрос... Какая-либо причина Вы не используете ORM?

1
ответ дан Simon 26 November 2019 в 23:37
поделиться

По некоторым причинам у меня были проблемы с выполнением проверки по сравнению с DBNull. Значение, таким образом, я сделал немного отличающиеся вещи и усилил свойство в объекте DataRow:

if (row.IsNull["fooColumn"])
{
   value = string.Empty();
}
{
else
{
   value = row["fooColumn"].ToString;
}
1
ответ дан Dillie-O 26 November 2019 в 23:37
поделиться

Я обычно пишу свой собственный класс ConvertDBNull, который обертывает встроенный класс Преобразования. Если значение будет DBNull, то это возвратит пустой указатель, если это будет ссылочный тип или значение по умолчанию, если это - тип значения. Пример: - ConvertDBNull.ToInt64(object obj) возвраты Convert.ToInt64(obj), если obj не является DBNull, в этом случае, это возвратится 0.

1
ответ дан Manu 26 November 2019 в 23:37
поделиться

Можно также протестировать с , Преобразовывают. IsDBNull (MSDN) .

1
ответ дан Pascal Paradis 26 November 2019 в 23:37
поделиться

Если Вы имеете контроль над запросом, который возвращает результаты, можно использовать ISNULL () для возврата ненулевых значений как это:

SELECT 
  ISNULL(name,'') AS name
  ,ISNULL(age, 0) AS age
FROM 
  names

, Если Ваша ситуация может терпеть эти волшебные значения для заменения ПУСТОЙ УКАЗАТЕЛЬ, проявляя этот подход, может устранить проблему через целое приложение, не создавая помехи коду.

5
ответ дан Steve Schoon 26 November 2019 в 23:37
поделиться

Я всегда находил его ясным, кратким, и проблема бесплатное использование версии Если/Еще проверка, только с тернарным оператором. Сохраняет все на одной строке, включая присвоение значения по умолчанию, если столбец является пустым.

Так, принимая nullable столбец Int32 по имени "MyCol", где мы хотим возвратиться-99, если столбец является пустым, но возвращает целочисленное значение, если столбец не является пустым:

return row["MyCol"] == DBNull.Value ? -99 : Convert.ToInt32(Row["MyCol"]);

Это - тот же метод как, Если/Еще победитель выше - Но я нашел, читаете ли Вы несколько столбцов в из datareader, это - реальная премия, имеющая все строки считанного из столбца один под другим, выстроенным в линию, поскольку легче определить ошибки:

Object.ID = DataReader["ID"] == DBNull.Value ? -99 : Convert.ToInt32(DataReader["ID"]);
Object.Name = DataReader["Name"] == DBNull.Value ? "None" : Convert.ToString(DataReader["Name"]);
Object.Price = DataReader["Price"] == DBNull.Value ? 0.0 : Convert.ToFloat(DataReader["Price"]);
8
ответ дан Meff 26 November 2019 в 23:37
поделиться

Добавьте ссылку на System.Data.DataSetExtensions, который добавляет поддержку Linq запросов таблиц данных.

Это было бы чем-то как:

string value = (
    from row in ds.Tables[0].Rows
    select row.Field<string>(0) ).FirstOrDefault();
8
ответ дан Keith 26 November 2019 в 23:37
поделиться

Если Вы не используете nullable типы, лучшая вещь сделать проверить, чтобы видеть, является ли значение столбца DBNull. Если это - DBNull, то установленный Ваша ссылка на то, что Вы используете для пустого/пустого для соответствующего типа данных.

DataRow row = ds.Tables[0].Rows[0];
string value;

if (row["fooColumn"] == DBNull.Value)
{
   value = string.Empty;
}
else 
{
   value = Convert.ToString(row["fooColumn"]);
}

, Поскольку Manu сказал, можно создать класс преобразования с перегруженным методом преобразования на тип, таким образом, Вы не должны перчить свой код если/еще блоки.

я однако подчеркну, что nullable типы являются лучшим маршрутом, чтобы пойти, если можно использовать их. Обоснование состоит в том, что с не допускающими NULL-значения типами, Вы оказываетесь перед необходимостью обращаться к "магическим числам" для представления пустого указателя. Например, при отображении столбца на международную переменную как Вы собираетесь представить DBNull? Часто Вы не можете использовать 0, потому что 0 имеет допустимое значение в большинстве программ. Часто я вижу, что люди отображают DBNull на интервал. MinValue, но это могло потенциально быть проблематично также. Мой лучший совет - это:

  • столбцы For, которые могут быть пустыми в базе данных, используют nullable типы.
  • столбцы For, которые не могут быть пустыми в базе данных, используют регулярные типы.

типы Nullable были сделаны решить эту проблему. Однако если Вы будете на более старой версии платформы или будете работать на кого-то, кто не делает grok nullable типов, пример кода добьется цели.

21
ответ дан Daniel Auger 26 November 2019 в 23:37
поделиться

DBNull реализует.ToString () как все остальное. Никакая потребность сделать что-либо. Вместо трудного броска назовите.ToString объекта () методом.

DataRow row = ds.Tables[0].Rows[0];
string value;

if (row["fooColumn"] == DBNull.Value)
{
   value = string.Empty;
}
else 
{
   value = Convert.ToString(row["fooColumn"]);
}

это становится:

DataRow row = ds.Tables[0].Rows[0];
string value = row.ToString()

DBNull. ToString () возвращает строку. Пустой

Я предположил бы, что это - лучшая практика, которую Вы ищете

3
ответ дан 26 November 2019 в 23:37
поделиться