RuntimeBinderInternalCompilerException при использовании Microsoft.SqlServer.Types с Dapper

.net dapper sql-server

Вопрос

Используя проект Sql Server Data Tools, целевая платформа которого установлена ​​в один из следующих:

  • SQL Server 2008
  • SQL Server 2012
  • SQL Server 2014

И развертывание в (localdb) \ Projects или (localdb) \ ProjectsV12

Вызов хранимой процедуры, возвращающей тип Geometry, Geography или HierachyId, такой как:

CREATE PROCEDURE [dbo].[SelectSqlGeometry]
    @x Geometry
AS
    SELECT @x as y
RETURN 0

Следующий код вызова:

var result = Connection.Query("dbo.SelectSqlGeometry", new { x = geometry }, commandType: CommandType.StoredProcedure).First();
bool isSame = ((bool)geometry.STEquals(result.y));

приводит к следующему исключению в строке STEquals.

Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException не был обработан кодом пользователя HResult = -2146233088 Сообщение = Произошло непредвиденное исключение при привязке динамической операции
Source = Microsoft.CSharp StackTrace: в Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind (полезная нагрузка DynamicMetaObjectBinder, 1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable IEnumerable 1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable 1 args, IEnumerable 1 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 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, LabelTarget returnLabel) в System.Runtime.CompilerServices.CallSiteBinder.BindCore [T] (сайт CallSite`1, Object [] args) в System.Dynamic.UpdateDelegates.UpdateAndExecute1 [T0, TRet] (сайт CallSite, T0 arg0) в DATailor.Examp les.Dapper.SqlClient.Test.AllTypesDAOTest.TestAllTypesDynamic ()

Принятый ответ

Хотя основная причина не Dapper, есть основное исключение, которое проглатывается.

Использование кода ADO.Net, например:

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();
}

Следующее исключение бросается на reader.GetValue

Ошибка System.InvalidCastException была необработанной. HResult = -2147467262
Сообщение = [A] Microsoft.SqlServer.Types.SqlGeometry нельзя использовать для [B] Microsoft.SqlServer.Types.SqlGeometry. Тип A происходит из «Microsoft.SqlServer.Types, Version = 10.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91» в контексте «По умолчанию» в месте «C: \ Windows \ assembly \ GAC_MSIL \ Microsoft.SqlServer.Types \ 10.0 .0.0__89845dcd8080cc91 \ Microsoft.SqlServer.Types.dll. Тип B начинается с «Microsoft.SqlServer.Types, Version = 11.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91» в контексте «По умолчанию» в месте «C: \ Windows \ assembly \ GAC_MSIL \ Microsoft.SqlServer.Types \ 11.0 .0.0__89845dcd8080cc91 \ Microsoft.SqlServer.Types.dll. Source = DynamicGeometryIssue StackTrace: в DynamicGeometryIssue.TestDao.TestGeometry () в c: \ Users \ rich \ Documents \ Visual Studio 2013 \ Projects \ DynamicGeometryIssue \ DynamicGeometryIssue \ TestDao.cs: строка 27 в DynamicGeometryIssue.Program.Main (String [] args ) в c: \ Users \ rich \ Documents \ Visual Studio 2013 \ Projects \ DynamicGeometryIssue \ DynamicGeometryIssue \ Program.cs: строка 15 в System.AppDomain._nExecuteAssembly (сборка RuntimeAssembly, String [] args) в System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String [] args) в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () в System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта) в System.Threading.ExecutionContext.RunInternal (ИсполнениеКонтекстовое исполнениеКонтекст, Обратный вызов ContextCallback, Object state, Boolean preserveSyncCtx) в System.Threading.ExecutionContext.Run (ExecutionContext executeContext, ContextCallback callback, состояние объекта, Boolean preserveSyncCtx) в System.Threading.Execu tionContext.Run (ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadHelper.ThreadStart () InnerException:

Причиной основного исключения является известное изменение в SQL Server 2012. См. Раздел « Типы данных SQL CLR » в следующей документации MSDN

http://msdn.microsoft.com/en-us/library/ms143179(v=sql.110).aspx

Резолюция, которая сработала для меня, заключается в создании следующего bindingRedirect в app.config или 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>

В качестве альтернативы, с .NET 4.5 вы можете изменить строку подключения, чтобы включить значение «SQL Server 2012» для атрибута «Тип системы», чтобы заставить SqlClient загрузить версию 11.0 сборки.

Другим обходным решением является код:

var geo = SqlGeography.Deserialize(rdr.GetSqlBytes(0));

Однако я не считаю, что это вариант с Dapper.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow