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: 1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding) at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable 、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 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 System.Runtime.CompilerServices.CallSiteBinder.BindCore [T](CallSite`1サイト、オブジェクト[] 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) args)をSystem.Dynamic.UpdateDelegates.UpdateAndExecute1 [T0、TRet](CallSiteサイト、T0 arg0)でDATailor.Exampプロパティ.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で次の例外がスローされreader.GetValue

System.InvalidCastExceptionが未処理のHResult = -2147467262
メッセージ= [A] Microsoft.SqlServer.Types.SqlGeometryは[B] Microsoft.SqlServer.Types.SqlGeometryにキャストできません。タイプAは、 'C:\ Windows \ assembly \ GAC_MSIL \ Microsoft.SqlServer.Types \ 10.0'のコンテキストで 'Default'というコンテキストで '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'のコンテキストで 'Default'というコンテキストで '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()(c:¥Users¥rich¥Documents¥Visual Studio 2013¥Projects¥DynamicGeometryIssue¥DynamicGeometryIssue¥TestDao.cs):27行目のDynamicGeometryIssue.Program.Main(String [] args) System.AppDomain.ExecuteAssembly(RuntimeAssemblyアセンブリ、String [] args)の15行目のc:\ Users \ rich \ Documents \ Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()System.Threading.ThreadHelper.ThreadStart_Context(Object state)at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallbackコールバック、Object)でのMicrosoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly(アセンブリファイル、Evidence assemblySecurity、String [] args)状態、ブールpreserveSyncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallbackコールバック、オブジェクト状態、ブールpreserveSyncCtx)でSystem.Threading.Execu System.Threading.ThreadHelper.ThreadStart()のwhenContentContext.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では、SqlClientにアセンブリのバージョン11.0を強制的に読み込ませるために、 "Type System Version"属性に "SQL Server 2012"の値を含めるように接続文字列を変更することができます。

別の回避策は次のようなコードです:

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

しかし、私はこれがDapperのオプションだとは思わない。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow