[seasar-dotnet:2228] [S2Dao.NET]ORACLEのストアド呼び出しでout stringパラメータを''で返すとInvalidCastExceptionが発生する

koala [E-MAIL ADDRESS DELETED]
2013年 2月 13日 (水) 21:00:59 JST


はじめまして。よろしくお願い致します。
Oracle11g(ODP.NET 2.111.6.20)ASP.NETでAOPを使用してORACLEストアドを呼び出しています。各定義は以下の通りです。

ITestDao.cs    [Bean(typeof(TestDaoEntity))]    public interface ITestDao    {        [Procedure("TESTPROC")]        void TESTPROC(out string p);    }
TestDaoEntity.cs    public class TestDaoEntity    {        //ストアド呼び出し用DAOのためのダミーエンティティ    }
CREATE OR REPLACE PROCEDURE TESTPROC(p OUT VARCHAR2)ISBEGIN    p := '';END;

このとき、TESTPROCの出力パラメータに''(長さゼロの文字列)をセットすると、以下の例外が発生します。何か値がセットされていれば例外は発生しません。
System.InvalidCastException はユーザー コードによってハンドルされませんでした。  Message=引数の戻り値の型が無効です。  Source=mscorlib  StackTrace:       場所 System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type paramType)       場所 System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage msg, Object[] outArgs, Object returnValue)       場所 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)       場所 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)  InnerException: 
Seasar.Framework.Aop.ProxyAopProxy.cs        public override IMessage Invoke(IMessage msg)        {        〜略〜            IMethodReturnMessage mrm = new ReturnMessage(ret, methodArgs, methodArgs.Length,                methodMessage.LogicalCallContext, (IMethodCallMessage) msg);
            return mrm;        }

正常パターンと見比べたところmrm.OutArgsがSystem.DBNullのときに例外となることがわかったので、ストアドの戻り値を取り出す処理に>の行を追加してみました。
Seasar.Dao.Impl.ObjectBasicProcedureHandler.cs
                    // OutまたはInOutパラメータ値を取得する                    for (int i = 0; i < args.Length; i++)                    {                        if (ArgumentDirection[i] == ParameterDirection.InputOutput ||                             ArgumentDirection[i] == ParameterDirection.Output)                        {>                            DbType dbType = GetDbValueType(ArgumentTypes[i]);>                            if ((dbType == DbType.String) && ((IDataParameter)cmd.Parameters[i + cnt]).Value is System.DBNull)>                            {>                                args[i] = "";>                            }>                            else>                            {                                args[i] = ((IDataParameter)cmd.Parameters[i + cnt]).Value;>                            }                        }                    }

これでとりあえず例外は回避できたのですが、そもそもこのやり方で良いのか、より良い(普通の)やり方があるのか、質問させて頂いた次第です。よろしくお願い致します。
 		 	   		  
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://ml.seasar.org/archives/seasar-dotnet/attachments/20130213/01ec83c9/attachment.html>


seasar-dotnet メーリングリストの案内