[seasar-dotnet:237] [S2Dao]SelectメソッドのDTO引数か否かの判定について
kubo
jazzflute @ mbn.nifty.com
2006年 6月 11日 (日) 00:04:02 JST
久保です。
○環境
WindowsXP SP2
VS2005 Team Edition
.NET 2.0
S2Container.NET 1.2.0-RC2 (.NET 2.0)
S2Dao.NET 0.4.2
{ASP開発}
DaoMetaDataImpl#SetupSelectMethodByAuto(MethodInfo)
における処理に関してです。
このメソッドでは、該当のSelectメソッドが、
- DTO引数を利用するのか?
- それとも引数をそのまま利用するのか?
を判定して、CreateAutoSelectSqlByDto(Type)とCreateAutoSelectSql(string[])
を呼び分ける部分があります。
そこの判定で少しおかしいかと思われる部分があります。
if(argNames.Length == 0 && mi.GetParameters().Length == 1) // ←★
{
argNames = new string[] { "dto" };
sql = CreateAutoSelectSqlByDto(argTypes[0]);
}
else
{
sql = CreateAutoSelectSql(argNames);
}
argNamesが0件でかつメソッドの引数の数が1つの場合に、DTO引数を
利用します。しかし、それら変数の定義を見ると:(以下)
string[] argNames = MethodUtil.GetParameterNames(mi);
これは、内部で mi.GetParameters(); のName属性をstring[]に
詰め替えています。なので、argNames.Lengthとmi.GetParameters().Lengthは
必ず同じ値になるのではないかと思います。
よって、CreateAutoSelectSqlByDto()が呼ばれません。(実際にやってみました)
恐らく、C#だとMethodの変数名を取得できるので、Java版に存在する
ARGS-Annotationを利用する必要がなく、
String[] argNames = annotationReader_.getArgNames(method);
が、↓↓↓
string[] argNames = MethodUtil.GetParameterNames(mi);
という実装になっていると思うのですが、
if(argNames.Length == 0 && mi.GetParameters().Length == 1) // ←
の判定がJava版と同じままになってしまっているのでこの現象が
起きているのかと思います。
Java版では、極端な話ARGS-Annotationの有無で判定をしているような
感じですが、ARGS属性を利用しないC#ではその判定ができません。
なので、ちょっとどのような判定をするのが正解なのかがわかりかねます。
とりあえず現状では、暫定で以下のように修正して対応しています。
if (argNames.Length == 1 && IsDtoTargetArgName(argNames[0])) {
argNames = new String[] { "dto" };
sql = CreateAutoSelectSqlByDto(argsTypes[0]);
// /----------------------------------------------------- [MyExtension]
if (LdConditionBeanContext.IsTheTypeConditionBean(argsTypes[0])) {
cmd = NewLdS2DaoSelectDynamicCommand(handler).SetSelectClause(sql);
}
// -----------/
...
protected virtual bool IsDtoTargetArgName(String name) {
if (name.Equals("dto") || name.Equals("entity") || name.Equals("cb")) {
return true;
} else {
return false;
}
}
引数が1個で、引数名がdtoやentityなどであればDTO引数として利用する。
[判定ロジック案]
A. 引数が1個で引数の名前が[dto/entity/...]であればDTO引数
B. 引数が1個で引数の型が[string/int/long/...]でなければDTO引数
C. 引数が1個で引数が「あるInterface」をImplementsしてる場合はDTO引数
など考えられます。
個人的には、Seasar.Dao内に、IDtoArgumentといった感じのInterfaceを
用意して、それをImplementsしてる場合はDTO引数とするのが良いかと
思っています。理由は、判定基準が利用者側にわかりやすいからです。
但し、Stringや既存のClassをDTOとして扱えないのでマズいのかも
しれません。
この辺はJava版の方の仕様とすり合わせる必要があるのかないのか
ちょっとわからないですが、A/B/Cもしくはその他の方法で、
CreateAutoSelectSqlByDtoが実行されるように修正を検討して
頂けませんでしょうか?
(勘違いしてたらごめんなさい)
--
kubo <jazzflute @ mbn.nifty.com>
seasar-dotnet メーリングリストの案内