jonwagner / Insight.Database

Fast, lightweight .NET micro-ORM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support SqlHierarchyId type for .NET Core

yegor-n-a opened this issue · comments

To avoid repetitions, I'll keep it short:

  1. Description
  2. Context
  3. Related issue
  4. How to fix
  5. Example: EF .Core implementaion

Are there any plans to implement aforementioned?

Thanks.

@jonwagner Any commentaries on that?

This seems to work for me (netcore):

void Main()
{
	var conn = new SqlConnection(MyExtensions.SQLConnectionString);
	SqlInsightDbProvider.RegisterProvider();

	var response = conn.QuerySql<Foo>("select 3 as [Id], hierarchyid::Parse('/1/2/3/') as [Path]");

        //Linqpad
	//response.Dump();
}

public class Foo
{ 
	public int Id { get; set; }
	public SqlHierarchyId Path { get; set; }
	
}

image

Any specific scenario that is not functioning properly?

@Jaxelr, @jonwagner I apologize for the late reply. I was a bit overloaded with the other tasks.

Unfortunately, I am unable to reproduce your successful story :(

My setup:

using Insight.Database;
using Microsoft.SqlServer.Types;
using System.Data.SqlClient;

namespace SqlHierarchyTesting
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlInsightDbProvider.RegisterProvider();

            using (var conn = new SqlConnection(MyExtensions.SqlConnectionString))
            {
                var response = conn.QuerySql<Foo>("select 3 as [Id], hierarchyid::Parse('/1/2/3/') as [Path]");
            }
        }

        public class Foo
        {
            public int Id { get; set; }
            public SqlHierarchyId Path { get; set; }
        }
    }
}

Config:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="dotMorten.Microsoft.SqlServer.Types" Version="1.1.0" />
    <PackageReference Include="Insight.Database" Version="6.2.11" />
  </ItemGroup>

</Project>

StackTrace:

   at Insight.Database.CodeGenerator.SchemaIdentity.CalculateHashCode()
   at Insight.Database.CodeGenerator.DbReaderDeserializer.GetDeserializer(IDataReader reader, Type type, IRecordStructure structure, SchemaMappingType mappingType)
   at Insight.Database.CodeGenerator.DbReaderDeserializer.GetDeserializer[T](IDataReader reader, IRecordStructure structure)
   at Insight.Database.DBReaderExtensions.AsEnumerable[T](IDataReader reader, IRecordReader`1 recordReader)+MoveNext()
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Insight.Database.Structure.ListReader`1.Read(IDbCommand command, IDataReader reader)
   at Insight.Database.DBConnectionExtensions.<>c__DisplayClass170_0`1.<Query>b__1(IDbCommand cmd, IDataReader r)
   at Insight.Database.DBConnectionExtensions.ExecuteAndAutoClose[T](IDbConnection connection, Func`2 getCommand, Func`3 translate, CommandBehavior commandBehavior)
   at Insight.Database.DBConnectionExtensions.Query[T](IDbConnection connection, String sql, Object parameters, IQueryReader`1 returns, CommandType commandType, CommandBehavior commandBehavior, Nullable`1 commandTimeout, IDbTransaction transaction, Object outputParameters)
   at Insight.Database.DBConnectionExtensions.QuerySql[T1](IDbConnection connection, String sql, Object parameters, CommandBehavior commandBehavior, Nullable`1 commandTimeout, IDbTransaction transaction, Object outputParameters)
   at SqlHierarchyTesting.Program.Main(String[] args) in D:\TEMP\InsightDatabase.SqlHierarchyTesting\SqlHierarchyTesting\Program.cs:line 15

Screenshot:

InsightDatabase SqlHierarchy Error

Have I missed something?

The only difference that i see from my version and your version, is that i used Microsoft.SqlServer.Types

image

and these were the using libs

image

Update: As i bet you could guess, the issue is the dotMorten.Microsoft.SqlServer.Types is not included as part of insight.database, and currently, there is no netstandard implementation of Microsoft.SqlServer.Types, there is an issue open here, which we could track.

You could try and make it work with Microsoft.SqlServer.Types nuget package, just maybe include suppresion for the warnings as part of your package reference:

<PackageReference Include="Microsoft.SqlServer.Types"  Version="14.0.1016.290">
        <NoWarn>NU1701</NoWarn>
</PackageReference>

Note that custom sql types work properly in net4x implementations.

I spent some time working on the netstandard implementations but didn't get that far yesterday.

This is the first I'm seeing the dotmorten code. We may be able to use that as a bridge for now. Will take another look at it.

It looks like dotmorten doesn't work with the new Microsoft.Data.SqlClient driver.

See dotMorten/Microsoft.SqlServer.Types#29

The main issue with these sqltypes is that the Sql driver does some special serialization on parameterization/recordset. It's automatic as long as the libraries can be loaded. However those libraries aren't portable yet.

We'll keep this open and watch the .NET core support for the standard types.

Now there is a dotMorten.Microsoft.SqlServer.Types v2.x : Depends on updated Microsoft.Data.SqlClient package.
See https://github.com/dotMorten/Microsoft.SqlServer.Types

Problem
When doing a select query containing a geography db field and having a DTO containing a SqlGeography property this throws an exception (see below).

Can you please help me. Do you have a solution for this problem? Can you make Insight.Database compatible with dotMorten.Microsoft.SqlServer.Types (v2.x)?

This problem probably relates to: #414

Exception

Message: 
*** threw exception: 
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.Type'.

  Stack Trace: 
ColumnInfo.FromDataReader(IDataReader reader)
DbReaderDeserializer.GetDeserializer(IDataReader reader, Type type, IRecordStructure structure, SchemaMappingType mappingType)
DbReaderDeserializer.GetDeserializer[T](IDataReader reader, IRecordStructure structure)
OneToOne`1.GetRecordReader(IDataReader reader)
<AsEnumerable>d__3`1.MoveNext()
List`1.ctor(IEnumerable`1 collection)
Enumerable.ToList[TSource](IEnumerable`1 source)
DBReaderExtensions.ToList[T](IDataReader reader, IRecordReader`1 recordReader)
ListReader`1.Read(IDbCommand command, IDataReader reader)
<>c__DisplayClass178_0`1.<Query>b__1(IDbCommand cmd, IDataReader r)
DBConnectionExtensions.ExecuteAndAutoClose[T](IDbConnection connection, Func`2 getCommand, Func`3 translate, CommandBehavior commandBehavior)
DBConnectionExtensions.Query[T](IDbConnection connection, String sql, Object parameters, IQueryReader`1 returns, CommandType commandType, CommandBehavior commandBehavior, Nullable`1 commandTimeout, IDbTransaction transaction, Object outputParameters)
DBConnectionExtensions.QuerySql[T1](IDbConnection connection, String sql, Object parameters, CommandBehavior commandBehavior, Nullable`1 commandTimeout, IDbTransaction transaction, Object outputParameters)

References

  • Insight.Database: 6.3.9
  • dotMorten.Microsoft.SqlServer.Types: 2.5.0
  • Microsoft.Data.SqlClient: 4.1.0

.NET Framework 4.7.2