Dapper에서 Microsoft.SqlServer.Types를 사용할 때 RuntimeBinderInternalCompilerException

.net dapper sql-server

문제

대상 플랫폼이 다음 중 하나로 설정된 SQL Server 데이터 도구 프로젝트 사용

  • 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 페이로드, IEnumerable 1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, 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 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable 1 인수, 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 System.Runtime.CompilerServices.CallSiteBinder.BindCore [T] (CallSite`1 site, Object [] 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)에서 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 args)를 System.Dynamic.UpdateDelegates.UpdateAndExecute1 [T0, TRet] (CallSite 사이트, T0 arg0)에서 DATailor.Examp ()

수락 된 답변

근본 원인이 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 다음 예외가 발생합니다. reader.GetValue

System.InvalidCastException 처리되지 않은 HResult = -2147467262
메시지 = [A] Microsoft.SqlServer.Types.SqlGeometry는 [B] Microsoft.SqlServer.Types.SqlGeometry로 캐스팅 될 수 없습니다. 형식 'C : \ Windows \ assembly \ GAC_MSIL \ Microsoft.SqlServer.Types \ 10.0'의 컨텍스트 '기본값'에서 'Microsoft.SqlServer.Types, Version = 10.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91' .0.0____89845dcd8080cc91 \ Microsoft.SqlServer.Types.dll '. 형식 B는 'C : \ Windows \ assembly \ GAC_MSIL \ Microsoft.SqlServer.Types \ 11.0'위치의 '기본값'컨텍스트에서 'Microsoft.SqlServer.Types, Version = 11.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91' .0.0____89845dcd8080cc91 \ Microsoft.SqlServer.Types.dll '. Source = DynamicGeometryIssue StackTrace : DynamicGeometryIssue.TestDao.TestGeometry () at c : \ Users \ rich \ Documents \ Visual Studio 2013 \ Projects \ DynamicGeometryIssue \ DynamicGeometryIssue \ TestDao.cs : 27 번째 줄 DynamicGeometryIssue.Program.Main (String [] args) System.AppDomain.ExecuteAssembly (RuntimeAssembly 어셈블리, String [] args)의 System.AppDomain._nExecuteAssembly에서 15 번째 줄 : c : \ Users \ rich \ Documents \ Visual Studio 2013 \ Projects \ DynamicGeometryIssue \ DynamicGeometryIssue \ System.Threading.ThreadHelper.ThreadStart_Context (Object state) at System.Threading.ExecutionContext.RunInternal (ExecutionContext executionContext, ContextCallback 콜백, 개체)에서 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()에서 assemblySile, Evidence assemblySecurity, String [] 상태, 부울 preserveSyncCtx)에서 System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback 콜백, 개체 상태, 부울 preserveSyncCtx)에서 System.Threading.Execu System.Threading.ThreadHelper.ThreadStart ()에서 6.ContentContext.Run (ExecutionContext executionContext, ContextCallback 콜백, 객체 상태) InnerException :

근본적인 예외의 원인은 SQL Server 2012의 알려진 주요 변경 사항입니다. 다음 MSDN 설명서의 SQL CLR 데이터 형식 섹션을 참조하십시오.

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

나에게 효과가 있었던 해결책은 app.config 또는 web.config에서 다음 bindingRedirect를 만드는 것입니다.

<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를 사용하면 "Type System Version"특성에 "SQL Server 2012"값을 포함하도록 연결 문자열을 변경하여 SqlClient가 어셈블리의 버전 11.0을 강제로로드 할 수 있습니다.

다른 해결 방법은 다음과 같은 코드입니다.

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

그러나 이것이 Dapper의 옵션이라고 생각하지 않습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.