Search code examples
c#.net-coregeolinq2db

Can't cast SqlGeography when withdrawing data from DB


I can't get SqlGeography object from MS SQL DB, I use .net core app and linq2db as the provider, but I have an exception: "Can't create 'GIS_CH_DB.sys.geography' type or '' specific type for Geometry."

But I'm use

var provider = (SqlServerDataProvider)DataConnection.GetRegisteredProviders()[LinqToDB.ProviderName.SqlServer2014];
            provider.AddUdtType<SqlGeography>("Geography", null, LinqToDB.DataType.Udt);
            provider.AddUdtType<SqlGeometry>("Geometry", null, LinqToDB.DataType.Udt);

which should cast SQLGeography to correct object. Does somebody know how to solve this issue?


Solution

  • Edit: added retrown instead of return null

    As it was mentioned in comments, this is due to version conflicts between spatial types assembly (Microsoft.SqlServer.Types), requested by sql client and actual assembly you have. While for .net framework application you can handle it using binding redirects, for .net core you cannot do it because:

    • no binding redirects in .net core
    • even if there will be any - they will not work due to different public keys

    You need to register custom assembly resolver to fix it (based on https://github.com/dotnet/core/issues/290#issuecomment-280451104):

    // somewhere in your init code
    AssemblyLoadContext.Default.Resolving += OnAssemblyResolve;
    
    Assembly OnAssemblyResolve(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
    {
      try
      {
        AssemblyLoadContext.Default.Resolving -= OnAssemblyResolve;
        return assemblyLoadContext.LoadFromAssemblyName(assemblyName);
      }
      catch
      {
        if (assemblyName.Name == "Microsoft.SqlServer.Types")
          return typeof(SqlGeography).Assembly;
        throw;
      }
      finally
      {
        AssemblyLoadContext.Default.Resolving += OnAssemblyResolve;
      }
    }
    

    I will update linq2db documentation to mention it and also check if we can improve this situation on our side