5

In my windows class library (consumed by a MVC website) I have installed the NugetPackage Microsoft.SqlServer.Types (Spatial).

Now, using ado.net I am trying to read the value by doing:

protected SqlGeography MapSqlGeography(DbDataReader reader, string key)
{
      return reader[key] is DBNull ? null : (SqlGeography)reader[key];
}

If I add a brake point in this line and in the visual studio watch window I type: "reader[key]", I can see the correct Point(XXXX,XXX) of type: "object {Microsoft.SqlServer.Types.SqlGeography}"

But, as soon as I try to make the cast I have the following error:

(SqlGeography)reader[key]   The type 'Microsoft.SqlServer.Types.SqlGeography' exists in both
 'Microsoft.SqlServer.Types.dll' and 
 'Microsoft.SqlServer.Types.dll'

Main strange fact is that the dlls are exactly the same...

As far as I know I only have one "source" for this namespace/class name, it should not be duplicated....

My "usings" are:

using Microsoft.SqlServer.Types;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Threading.Tasks;

Any ideas on how to solve this? Thanks.

Update #1

I uninstalled the NugetPackage `Microsoft.SqlServer.Types (Spatial)' and instead tried the one called: 'Microsoft.SqlServer.Types (Unofficial)' and even after cleaning all the previous folders/files and also cleaning up the "bin/obj", I continue to have the exact same exception....

I simply do now see the cause of this now.... any ideas would be really appreciated.

Update #2

Just tried to use extern alias destination;

return reader[key] is DBNull 
        ? null 
        : (destination.Microsoft.SqlServer.Types.SqlGeography)reader[key];

And have the exception:

Cannot cast 'reader[key]' (which has an actual type of 'Microsoft.SqlServer.Types.SqlGeography') 
to 
'Microsoft.SqlServer.Types.SqlGeography'
Microsoft.SqlServer.Types.SqlGeography
Dryadwoods
  • 2,875
  • 5
  • 42
  • 72
  • Is the dll included in your project twice somehow? – Alfie Goodacre Dec 02 '16 at 10:07
  • I had this issue once in azure db project and it was related to invalid version of that dll that I was using. Compare versions and make sure you are using right one. – Rafal Dec 02 '16 at 10:10
  • 1
    You have references to two distinct versions of the same assembly. Without applying aliases, the system has no way of knowing which specific type(s) you're referring to since multiple assemblies can contain types from the same namespaces, including types with identical names within the same namespaces. (Especially, as here, where you have two different versions of the same assembly, it's not that surprising that they contain types of the same names) – Damien_The_Unbeliever Dec 02 '16 at 10:35
  • (Not that I'd recommend introducing aliases - it's far more likely that your references to multiple versions of the assembly are by accident and you should resolve that so that you only have a reference to a single version) – Damien_The_Unbeliever Dec 02 '16 at 10:36
  • @Damien_The_Unbeliever if I correctly used your approach on my Update #2, then it seems that it didn't work.... :( – Dryadwoods Dec 05 '16 at 14:08

3 Answers3

3

I encountered this error today because a referenced library included a different version of Microsoft.SqlServer.Types from Nuget than the locally installed one.

You can install a matching version using Nuget to resolve the issue, or you may be able to use binding redirects if that is not an option.

For example:

Install-Package Microsoft.SqlServer.Types -Version 10.50.1600.1

Check your specific versions by looking at package.json for your dependencies, or perhaps you can check the DLL properties directly.

jocull
  • 20,008
  • 22
  • 105
  • 149
2

The runtime uses the following steps to resolve an assembly reference:

  1. Determines the correct assembly version by examining applicable configuration files, including the application configuration file, publisher policy file, and machine configuration file. If the configuration file is located on a remote machine, the runtime must locate and download the application configuration file first.
  2. Checks whether the assembly name has been bound to before and, if so, uses the previously loaded assembly.
  3. Checks the global assembly cache. If the assembly is found there, the runtime uses this assembly.
  4. Probes for the assembly using the following steps:
    • If configuration and publisher policy do not affect the original reference and if the bind request was created using the Assembly.LoadFrom method, the runtime checks for location hints.
    • If a codebase is found in the configuration files, the runtime checks only this location. If this probe fails, the runtime determines that the binding request failed and no other probing occurs.
    • Probes for the assembly using the heuristics described in the probing section. If the assembly is not found after probing, the runtime requests the Windows Installer to provide the assembly. This acts as an install-on-demand feature. Note There is no version checking for assemblies without strong names, nor does the runtime check in the global assembly cache for assemblies without strong names.

Now, check to see if you have multiple assemblies referenced (as Damien_The_Unbeliever said in the comment) or you do not have specific version set for that assembly.

Also you can try the Assembly Binding Log Viewer (Fuslogvw) to see exactly what gets loaded and what are the search paths.

Mihail Stancescu
  • 4,088
  • 1
  • 16
  • 21
1

Try using this in your web.config file:

 <dependentAssembly>
      <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
      <bindingRedirect oldVersion="10.0.0.0-11.0.0.0" newVersion="14.0.0.0" />
  </dependentAssembly>
Anu Singh
  • 19
  • 3