dotnet / SqlClient

Microsoft.Data.SqlClient provides database connectivity to SQL Server for .NET applications.
MIT License
836 stars 277 forks source link

InvalidCastException using DateOnly in SqlDataRecord #2687

Open alansingfield opened 1 month ago

alansingfield commented 1 month ago

Describe the bug

Attempting to pass a DateOnly value into a SqlDataRecord causes an InvalidCastException.

Exception message:
System.InvalidCastException
  HResult=0x80004002
  Message=Specified cast is not valid.
  Source=Microsoft.Data.SqlClient
  StackTrace:
   at Microsoft.Data.SqlClient.Server.SqlDataRecord.SetValueFrameworkSpecific(Int32 ordinal, Object value)
   at Microsoft.Data.SqlClient.Server.SqlDataRecord.SetValue(Int32 ordinal, Object value)
   at Program.<Main>$(String[] args) in C:\Users\(username)\Scrapbook\SqlClientNetVer\SqlClientNetVer\Program.cs:line 8

To reproduce

Create a net8.0 console application, and use Nuget to reference Microsoft.Data.SqlClient.dll

using Microsoft.Data.SqlClient.Server;

var meta = new SqlMetaData(
    "mycolumn",
    System.Data.SqlDbType.Date);

var dr = new SqlDataRecord([meta]);
dr.SetValue(0, new DateOnly(1994,1,1));

Expected behavior

The DateOnly value is written into the SqlDataRecord and it doesn't raise an exception on the SetValue() call.

Further technical details

Microsoft.Data.SqlClient version: 5.2.1 .NET target: net8.0 SQL Server version: SQL Server 2022 Operating system: Windows 11

Additional context

Looking through the code in github, it appears as if this SHOULD be supported, it is conditionally compiled in with NET6_0_OR_GREATER DetermineExtendedTypeCodeForUseWithSqlDbType() within MetaDataUtilsSmi

But when I find the exact DLL which is being referenced, this does not have any of the net8.0 features in it. The DLL being loaded is C:...\bin\Debug\net8.0\runtimes\win\lib\net8.0

Is this a fault in how the build / package process is running? E.g. the wrong conditional compilation flags being applied or the DLLs going into the wrong place in the package?

ErikEJ commented 1 month ago

Maybe I only fixed this in 6.0 and it was not backported?

alansingfield commented 1 month ago

Same issue occurs on .net6.0 I'm fairly sure, since I discovered this in a much larger .net6.0 project - but wrote the repro case in .net8.0.

If I load symbols in Visual Studio and single-step through the code of Microsoft.Data.SqlClient.dll - it looks weird, the code shown is that of the .netfx version rather than .netcore - but VS is greying out the code between #ifdef NETFRAMEWORK .

DLL loaded is in from a folder like \bin\Debug\net8.0\runtimes\win\lib\net8.0 suggesting that the DLL chosen to load by the loader has the correct filename. Which is why I'm suspecting some kind of packaging problem.

I've cleared out my .nuget package cache and confirmed that the nuget restore pulled this file back out again.

ErikEJ commented 1 month ago

I mean main branch (SqlClient 6.0), not net 6.0!

kf-gonzalez2 commented 1 month ago

Keeping this issue open to track backporting of the fix. This issue should be related to #2209