Using a Sql Server Data Tools project whose target platform is set to one of:
And deploying to (localdb)\Projects or (localdb)\ProjectsV12
Calling a stored procedure that returns a Geometry, Geography or HierachyId type such as:
CREATE PROCEDURE [dbo].[SelectSqlGeometry]
@x Geometry
AS
SELECT @x as y
RETURN 0
The following calling code:
var result = Connection.Query("dbo.SelectSqlGeometry", new { x = geometry }, commandType: CommandType.StoredProcedure).First();
bool isSame = ((bool)geometry.STEquals(result.y));
results in the following exception on the STEquals line.
Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException was unhandled by user code HResult=-2146233088 Message=An unexpected exception occurred while binding a dynamic operation
Source=Microsoft.CSharp StackTrace: at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable
1 args, IEnumerable1 arginfos, DynamicMetaObject onBindingError) at Microsoft.CSharp.RuntimeBinder.CSharpConvertBinder.FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion) at System.Dynamic.DynamicMetaObject.BindConvert(ConvertBinder binder) at System.Dynamic.ConvertBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args) at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection
1 parameters, LabelTarget returnLabel) at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at DATailor.Examples.Dapper.SqlClient.Test.AllTypesDAOTest.TestAllTypesDynamic()
Although the root cause is not Dapper, there is an underlying exception that is being swallowed.
Using ADO.Net code like:
var geometry = Util.CreateSqlGeometry();
SqlDataReader reader=null;
SqlCommand cmd=null;
try
{
cmd = new SqlCommand("dbo.SelectSqlGeometry", (SqlConnection)Connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@x", geometry) { UdtTypeName = "Geometry" });
cmd.ExecuteNonQuery();
reader = cmd.ExecuteReader();
while (reader.Read())
{
var y = (SqlGeometry)reader.GetValue(0);
var same = geometry.STEquals(y);
}
reader.Dispose();
reader = null;
}
finally
{
if (reader != null)
{
if (!reader.IsClosed) try { cmd.Cancel(); }
catch {}
reader.Dispose();
}
if (cmd != null) cmd.Dispose();
Connection.Close();
}
The following exception is thrown at reader.GetValue
System.InvalidCastException was unhandled HResult=-2147467262
Message=[A]Microsoft.SqlServer.Types.SqlGeometry cannot be cast to [B]Microsoft.SqlServer.Types.SqlGeometry. Type A originates from 'Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' in the context 'Default' at location 'C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Types\10.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll'. Type B originates from 'Microsoft.SqlServer.Types, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' in the context 'Default' at location 'C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Types\11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll'. Source=DynamicGeometryIssue StackTrace: at DynamicGeometryIssue.TestDao.TestGeometry() in c:\Users\rich\Documents\Visual Studio 2013\Projects\DynamicGeometryIssue\DynamicGeometryIssue\TestDao.cs:line 27 at DynamicGeometryIssue.Program.Main(String[] args) in c:\Users\rich\Documents\Visual Studio 2013\Projects\DynamicGeometryIssue\DynamicGeometryIssue\Program.cs:line 15 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:
The cause of the underlying exception is a known breaking change in SQL Server 2012. See the SQL CLR Data Types section of the following MSDN documentation
http://msdn.microsoft.com/en-us/library/ms143179(v=sql.110).aspx
The resolution, that has worked for me is to create the following bindingRedirect in the app.config or web.config.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.SqlServer.Types"
publicKeyToken="89845dcd8080cc91"
culture="neutral" />
<bindingRedirect oldVersion="10.0.0.0"
newVersion="11.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Alternately, with .NET 4.5 you can change your connection string to include a value of "SQL Server 2012" for the "Type System Version" attribute to force SqlClient to load version 11.0 of the assembly.
Another workaround is code like:
var geo = SqlGeography.Deserialize(rdr.GetSqlBytes(0));
However, I don't believe this is an option with Dapper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With