Microsoft.SqlServer.Types icon indicating copy to clipboard operation
Microsoft.SqlServer.Types copied to clipboard

DataReader.GetFieldType returned null

Open vishnu4 opened this issue 3 years ago • 10 comments
trafficstars

This is basically a copy of https://github.com/dotMorten/Microsoft.SqlServer.Types/issues/32 . I can provide more info in my case:

.net core 6 project using Microsoft.Data.SqlClient, Method is:

      public virtual DataTable ExecuteProcedure(string cnnString, string theProcedure, IEnumerable<IDataParameter> theParameters)
       {
           DataTable dt = null;
           using (DataSet ds = new DataSet())
           {
               ds.Locale = System.Globalization.CultureInfo.InvariantCulture;
               using (SqlConnection cnn = new SqlConnection(cnnString))
               {
                   try
                   {
                       cnn.Open();
                       using (SqlCommand cmd = new SqlCommand(theProcedure, cnn))
                       {
                           // cmd.Prepare()	'use for large databases?
                           using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                           {
                               cmd.CommandType = CommandType.StoredProcedure;
                               if (theParameters != null && theParameters.Any())
                               {
                                   foreach (IDataParameter theParam in theParameters)
                                   {
                                           cmd.Parameters.Add(theParam.FormatParamValue());
                                   }
                               }
                               da.Fill(ds);
                           }
                       }
                   }
                   finally
                   {
                       if (cnn != null && cnn.State != ConnectionState.Closed)
                       {
                           cnn.Close();
                       }
                   }
               }
               if (!(ds == null) && !(ds.Tables == null) && (ds.Tables.Count > 0))
               {
                   dt = ds.Tables[0];
               }
           }
           return dt;
       }

if i run this against a stored procedure that's just

create PROCEDURE [dbo].[Organization_List] 
AS
BEGIN
	SET NOCOUNT ON;
SELECT
OrganizationGUID,
OrganizationName,
OrgGeometry
FROM dbo.Organization

END

with a table

CREATE TABLE [dbo].[Organization](
	[OrganizationName] [nvarchar](100) NOT NULL,
	[OrgGeometry] [geometry] NULL,
	[OrganizationGUID] [uniqueidentifier] NOT NULL
GO

and add some fake data

declare @g geometry = geometry::STGeomFromText(
    'POINT (22.9901232886963 87.5953903123242)'
    , 4326);
INSERT INTO Organization (OrganizationName,OrgGeometry,OrganizationGUID) VALUES('Test',@g,newid())

Then you get the error above, with or without installing your package to the application.

vishnu4 avatar Feb 12 '22 20:02 vishnu4

I believe this is just a known limitation of using custom CLR types that are essentially different from the ones SqlServer uses (while they are the same in functionality and namespace, they are different because the assemblies each of them are defined in aren't signed with the same key, and there's not really any way I can "fake" that).

dotMorten avatar Feb 17 '22 00:02 dotMorten

Actually try adding this to your application startup:

https://github.com/dotMorten/Microsoft.SqlServer.Types/blob/cb48637ef78d36f4b2333d9b7a0f451d193f4316/src/Microsoft.SqlServer.Types.Tests/AssemblyLoader.cs#L21-L33

dotMorten avatar Feb 17 '22 00:02 dotMorten

Unfortunately that didn't work for me, i even tried SqlGeometry (since that is what i'm generally using) and still no good.

Does it matter where in startup.cs it's run? I had it running in Configure near the beginning, but not sure if other options were better.

Thanks!

vishnu4 avatar Feb 19 '22 18:02 vishnu4

I’ve actually been unable to reproduce this. Even the unit tests “just works” with that API call. Any chance you could share a self-contained application that reproduces this?

dotMorten avatar Feb 19 '22 18:02 dotMorten

Another thing you could try that might just do the trick is to explicitly load the assembly up-front before querying anything.

dotMorten avatar Mar 01 '22 20:03 dotMorten

I am having the same issue. Tried adding assembly resolve to app.config, also tried with AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; and still I get that error.

I am running net472 console app which references .netstandard2.0 project which contains the code for querying data.

dejanberic avatar Mar 02 '22 16:03 dejanberic

I am running net472 console app

Do not use this library if you use .NET Framework, but instead use the official Microsoft SDK. This library here is to fill the gap for .NET Core and Xamarin developers.

dotMorten avatar Mar 02 '22 20:03 dotMorten

I am having an issue where I have a lot of apps (WebApps, Console, Azure Cloud Services, Azure Functions) which needed to be converted to .NET 6. Now, all of them reference my DB class library, and I wanted to migrate to .NET 6 in small steps, one app at a time, where my DB class library and all other class libraries would target .netstandard2.0 except those main apps (web, console etc.).

How can I migrate in steps while using the official Microsoft SDK and targeting .netstandard2.0?

dejanberic avatar Mar 02 '22 22:03 dejanberic

I’d recommend multi targeting your class library instead

dotMorten avatar Mar 03 '22 02:03 dotMorten

Thanks, it works when I multitargeted to net472 and net6.0.

dejanberic avatar Mar 03 '22 10:03 dejanberic