SqlParameter DbType.Date -> SqlDbType.DateTime Conversion

2.6k views Asked by At

I'm using the generic IDbCommand functions (in non SqlCommand helper methods) to set SqlCommand.DbType to DbType.Date similar to this:

        var param = command.CreateParameter();

        param.DbType = DbType.Date;
        param.ParameterName = field;
        param.Value = ToDb(val);

        command.Parameters.Add(param);

And the resulting param.DbType is overriden to DbType.DateTime. (I intentionally want SqlDbType.Date, since the column/index is of Sql Server type Date, not DateTime.) Sure enough, when I decompile, I see that SqlParameter.DbType set calls MetaType.GetMetaTypeFromDbType, which has this:

internal static MetaType GetMetaTypeFromDbType(DbType target)
{
  switch (target)
  {
    ... 

    case DbType.Date:
    case DbType.DateTime:
      return MetaType.MetaDateTime;
  }
}

So the forced conversion is intentional and instead I have to do something hacky like:

        var param = command.CreateParameter();

        var sqlParam = param as SqlParameter;
        if (sqlParam != null)
        {
            sqlParam.SqlDbType = SqlDbType.Date;
        }
        else
        {
            param.DbType = DbType.Date;
        }

        param.ParameterName = field;
        param.Value = ToDb(val);

        command.Parameters.Add(param);

My question is why the forced conversion? Is this a carry over from earlier versions of Sql Server/framework where perhaps Date didn't exist and it was reasonable to assume folks wouldn't know the difference between DbType.Date and DbType.DateTime? Or is there something more fundamental going on?

Is there an actual workaround without special casing SqlParameter?

(I found surprisingly few references this searching this morning, so perhaps there's something much more obvious I'm just missing before another round of caffeine? Always appreciated!)

1

There are 1 answers

0
Malcolm On

For reference, as I just had to work around this myself:

Permalink (as it's moved)

Current (as of 2018-04-11)