1

Is there a way to shorthand the if/else statement below?

if (txtInvoiceDate.Text != "")
{
    query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value = DateTime.Parse(txtInvoiceDate.Text.ToString());
}
else
{
    query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value = DBNull.Value;
}
kevorski
  • 816
  • 1
  • 11
  • 29

5 Answers5

3
        query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value =
            string.IsNullOrWhiteSpace(txtInvoiceDate.Text)
                ? (DateTime?)DBNull.Value
                : DateTime.Parse(txtInvoiceDate.Text);
Fran
  • 6,440
  • 1
  • 23
  • 35
2
  • You call String.ToString() unnecessarily.
  • Your code doesn't handle the case of non-empty, but invalid, input.

My version:

{
    Object paramValue = DBNull.Value;
    DateTime value;
    if( DateTime.TryParse( txtInvoiceDate.Text, out value ) ) {
        paramValue = value;
    }
    query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value = paramValue;
}

Note my use of {} anonymous scopes so the paramValue and value variables don't pollute the local scope.

If you find yourself doing this often, you can change it to a method:

static SqlParameter AddDateParameter(SqlCommand cmd, String parameterName, String inputValue) {
    SqlParameter p = cmd.CreateParameter();
    p.Name = parameterName;
    p.SqlDbType = SqlDbType.SmallDateTime;
    cmd.Parameters.Add( p );

    DateTime value;
    if( DateTime.TryParse( inputValue, out value ) ) {
        p.Value = value;
    }
    else {
        p.Value = DBNull.Value;
    }
    return p; // return `p` in case the caller wants to modify the parameter further
}

Used like so:

AddDataParameter( query, "@InvoiceDate", txtInvoiceDate.Text );

As an aside, it might be an idea to replace txtInvoiceDate (which I assume is a TextBox) with a DateTimePicker control instead, which would outright prevent invalid input and also expose a strongly-typed DateTime value directly, without the need to use DateTime.TryParse.

Dai
  • 141,631
  • 28
  • 261
  • 374
1
query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value = 
    (!string.IsNullOrEmpty(txtInvoceDate.Text) ? 
      DateTime.Parse(txtInvoiceDate.Text) : 
      DBNull.Value);
Hemi81
  • 578
  • 2
  • 15
  • 34
0

I would create a simple extension for this.

public delegate bool TryParseHandler<T>(string value, out T result);

public static T? DbNullOrValue<T>(this string input, TryParseHandler<T> handler) where T : struct, IConvertible
{
    T res;
    if (!string.IsNullOrEmpty(input))
        if(handler(input, out res))
            return res;

    return null;
}

which can then be called anywhere like:

"12/13/15".DbNullOrValue<DateTime>(DateTime.TryParse)

EDIT: Taking from Generic TryParse I update the above code to also check if it can be converted before actually converting, pretty interesting technique.

Community
  • 1
  • 1
Dispersia
  • 1,436
  • 9
  • 23
0

Thanks for all the answers guys. When I tried to use:

query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value =
        string.IsNullOrWhiteSpace(txtInvoiceDate.Text)
            ? DBNull.Value
            : DateTime.Parse(txtInvoiceDate.Text);

I was getting an error that said

Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'System.DateTime'

In order to solve this, I had to use:

query.Parameters.AddWithValue("@InvoiceDate", SqlDbType.SmallDateTime).Value = (string.IsNullOrEmpty(txtInvoiceDate.Text) ? (DateTime?)null : DateTime.Parse(txtInvoiceDate.Text));
kevorski
  • 816
  • 1
  • 11
  • 29