5

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!)

Gene
  • 1,587
  • 4
  • 18
  • 38
  • 3
    You don't need to decompile - you can see it on github : https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/SqlParameter.cs#L207. "Two special datetime cases for backward compat DbType.Date and DbType.Time should always be treated as setting DbType.DateTime instead" Pretty annoying - and no, I can't see an easy workaround :( – Jon Skeet Jan 06 '17 at 17:13
  • Ah, fair point! And I guess that pretty much answers it - MS back compat choice (we now need to work around). Should have know you'd have an immediate and decisive answer sir - grazie! – Gene Jan 06 '17 at 17:16
  • 1
    (Incidentally that's pretty much what I was looking for. Know you're hardly starved for rep, but if you post as an answer it's all yours. :)) – Gene Jan 06 '17 at 17:42

1 Answers1

0

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

Permalink (as it's moved)

Current (as of 2018-04-11)

Malcolm
  • 1,239
  • 1
  • 14
  • 25