лучшее решение для значения Null DateTime - PullRequest
0 голосов
/ 26 августа 2010

Я не смог найти лучшего решения, когда значение DateTime равно NULL.

Я использую эту технику при связывании;

_ACTIVATION_DATE = dt.Rows[0]["ACTIVATION_DATE"] == DBNull.Value ? new DateTime(1970, 12, 30) : (DateTime?)dt.Rows[0]["ACTIVATION_DATE"];

При вставке;

public void Insert()
{
    string ad="";
    string dd="";

    if (ACTIVATION_DATE == null)
        ad = "null";
    else
        ad = "'" + ACTIVATION_DATE + "'";
    if (DEACTIVATION_DATE == null)
        dd = "null";
    else
        dd = "'" +DEACTIVATION_DATE +"'";

    string sSQL = "INSERT INTO LINE_INFO (ACTIVATION_DATE,DEACTIVATION_DATE,STATUS,PO,NOTES) VALUES (" + ad + "," + dd + "," + _STATUS.ToString() + "," + _PO.ToString() + ",'" + _NOTES.ToString() + "');SELECT @@IDENTITY AS LASTID";
    }

Переменные;

DateTime? ACTIVATION_DATE;
DateTime? DEACTIVATION_DATE;

Каков умный способ обработки нулевых значений DateTime?

Когда я найду решение, я напишу статью на эту тему.

Ответы [ 4 ]

4 голосов
/ 26 августа 2010

Почему вы используете new DateTime(1970, 12, 30), когда уже используете обнуляемый DateTime?Весь смысл типов значений, допускающих значение NULL, заключается в том, что вам не нужны такие магические значения.

Я мог бы использовать:

_ACTIVATION_DATE = dt.Rows[0]["ACTIVATION_DATE"] as DateTime?;

Это автоматически использует нулевое значение для любое значение не DateTime.Конечно, это означает, что вы получите нулевое значение вместо исключения, если у вас случайно будет целое число или что-то в этом роде.В качестве альтернативы:

object tmp = dt.Rows[0]["ACTIVATION_DATE"];
_ACTIVATION_DATE = tmp is DbNull ? null : (DateTime?) tmp;

Тогда для оператора вставки не включает значения непосредственно в ваш SQL .Используйте параметризованный оператор вставки, а затем вы можете просто использовать нулевое значение DateTime?, чтобы вставить нулевое значение.Нет необходимости возиться с форматами строк.

1 голос
/ 26 августа 2010

DateTime? подразумевает, что вы используете Nullable<DateTime> для хранения значения - так почему бы просто не использовать .HasValue и .Value?

0 голосов
/ 26 августа 2010

Обработка нуля. В большинстве случаев это зависит от потребностей бизнеса, в вашем случае кажется, что вам нужно сохранить какое-то значение, но информация о том, что дата равна нулю, иногда бывает полезна.Потому что что-то еще не произошло.Поэтому сложно определить хороший подход к обработке нулевых дат.

В вашем случае, что можно сделать, чтобы заменить new DateTime(1970, 12, 30) статическим полем const, называемым датой по умолчанию.

public const DateTime DEFAULT_DATE = new DateTime(1970,12,30);


public void Insert()
{
  string activationDate = "null";
  string deactivationDate= "null";

  if (ACTIVATION_DATE != null) {
   ad = string.format("'{0}'",ACTIVATION_DATE); //Hire should be some date format used
  }

  if (DEACTIVATION_DATE != null) {
   ad = string.format("'{0}'",DEACTIVATION_DATE); //Hire should be some date format used
  }


   string sSQL = string.format("INSERT INTO LINE_INFO (ACTIVATION_DATE,DEACTIVATION_DATE,STATUS,PO,NOTES) VALUES ({0},{1},{2},{3},'{4}');SELECT @@IDENTITY AS LASTID",activationDate ,deactivationDate ,_STATUS,_PO,_NOTES);

Ps.Вы не должны использовать этот тип создания операторов, вместо этого вы должны использовать SqlCommand и paramteres

0 голосов
/ 26 августа 2010

Вы не должны вставлять значения напрямую, потому что вы создаете возможность для SQL-инъекций. Вместо этого вы должны использовать параметризованные запросы:

using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
    command.CommandText = "INSERT INTO table1 (column1, column2) VALUES (@param1, @param2)";

    command.Parameters.Add("@param1", SqlDbType.DateTime).Value = 
        DateTime.TryParse(txtDate.Text, out d) ?
            (object)d :
            DBNull.Value // inserting NULL
    ...

    connection.Open();
    command.ExecuteNonQuery();
}

При переплете:

object date = reader["date"]; // NULL or '2010-08-26'
txtDate.Text = Convert.IsDBNull(date) ? (DateTime)date : String.Empty;
// or
txtDate.Text = (reader["date"] as DateTime? ?? String.Empty).ToString();
...