【问题标题】:RuntimeBinderInternalCompilerException when using Microsoft.SqlServer.Types with Dapper将 Microsoft.SqlServer.Types 与 Dapper 一起使用时出现 RuntimeBinderInternalCompilerException
【发布时间】:2014-09-01 06:34:24
【问题描述】:

使用目标平台设置为以下之一的 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 Message=An 绑定动态操作时发生意外异常
来源=Microsoft.CSharp StackTrace: 在 Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder 有效载荷,IEnumerable1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable1 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, ReadOnlyCollection1 参数,LabelTarget returnLabel) 在 System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 网站,对象 [] 参数) 在 System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,Tret](CallSite 站点,T0 arg0) 在 DATAilor.Examples.Dapper.SqlClient.Test.AllTypesDAOTest.TestAllTypesDynamic()

【问题讨论】:

    标签: .net sql-server dapper


    【解决方案1】:

    虽然根本原因不是 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
    Message=[A]Microsoft.SqlServer.Types.SqlGeometry 无法转换为 [B]Microsoft.SqlServer.Types.SqlGeometry。 A型起源于 'Microsoft.SqlServer.Types,版本=10.0.0.0,文化=中性, 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'。 来源=DynamicGeometryIssue StackTrace: 在 c:\Users\rich\Documents\Visual Studio 中的 DynamicGeometryIssue.TestDao.TestGeometry() 2013\Projects\DynamicGeometryIssue\DynamicGeometryIssue\TestDao.cs:line 27 在 c:\Users\rich\Documents\Visual Studio 中的 DynamicGeometryIssue.Program.Main(String[] args) 2013\Projects\DynamicGeometryIssue\DynamicGeometryIssue\Program.cs:line 15 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 保留SyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback 回调, 对象状态, Boolean 保留SyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 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,您可以更改连接字符串以包含“类型系统版本”属性的值“SQL Server 2012”,以强制 SqlClient 加载版本 11.0 的程序集。

    另一种解决方法是如下代码:

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

    但是,我不认为这是 Dapper 的一个选项。

    【讨论】:

      猜你喜欢
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2012-03-26
      • 2021-02-28
      • 2017-10-19
      • 2017-12-04
      • 2022-01-04
      相关资源
      最近更新 更多