[seasar-dotnet:470] Re: S2Container.NET S2Dao.NET Nullableな列挙型プロパティへのデータのマッピングへの対応要望

Kazuya Sugimoto sugimotokazuya @ gmail.com
2007年 3月 2日 (金) 18:25:06 JST


杉本です。

羽田さん、すいません。反応が遅くなりました。

ソースコードありがとうございます。

Nullableな列挙体に対応したいと思います。

07/03/01 に t.hada<t_hada @ atlascorp.co.jp> さんは書きました:
> お世話になります。
> 羽田と申します。
>
> S2Dao.NET 1.0.3利用時に列挙型のプロパティにデータをマップすることができ
> ていたので、
> .NET2.0のNullableな列挙体のプロパティにデータをマップしてみたところ、
> Nullableな列挙体に変換できないとのエラーが発生してしまいました。
>
> 原因を調査しましたところ、Seasar.Extension.ADO.ValueTypesは
> 明示的に列挙型向けの実装をしておらず、
> 通常の列挙型への変換はSystem.Reflection.PropertyInfoの動作として
> 行われているらしいことがわかりました。
>
> 列挙型の利用はステータス系のプロパティに関する生産性を
> 向上させると思いますので対応していただけると嬉しいです。
>
> Nullableな列挙型についてはNullableEnumType<TEnum>のようなものを実装し、
> 列挙型ごとに個別登録すれば対応できるような気もするのですが、
> 列挙型やNullable型であれば汎用的な実装が提供可能と思いますので、
> 一応、要望としてあげさせていただきます。
>
> 検討よろしくお願いします。
>
>
> お願いするだけではなんですので、
> 一応、技術的な参考としての実装は作成してみました。
>
> 大雑把に説明すれば列挙型、Nullableな列挙型に対応する汎用的なEnumType、
> NullableEnumTypeを用意いたしまして、ValueTypes.GetValueType(Type type)にて
> 特別視して解決しています。
> 一部、明示的にDbTypesを指定する必要がある場所につきましては、
> 列挙型の元となるデータ型を元にIValueTypeを解決し元となるデータ型の
> IValueTypeへ委譲しています。
>
> = Seasar.Extension.ADO.ValueTypes.EnumType
>
> using System;
> using System.Data;
>
> namespace Seasar.Extension.ADO.Types
> {
> public class EnumType : PrimitiveBaseType, IValueType
> {
> private Type enumType;
> private Type underlyingType;
> private IValueType underlyingValueType;
>
> public EnumType(Type enumType)
> {
> this.enumType = enumType;
> this.underlyingType = Enum.GetUnderlyingType(this.enumType);
> this.underlyingValueType = ValueTypes.GetValueType(this.underlyingType);
> }
>
> public override void BindValue(IDbCommand cmd, string columnName, object
> value)
> {
> object convertedValue = value == null ?
> null :
> Convert.ChangeType(value, this.underlyingType);
> this.underlyingValueType.BindValue(cmd, columnName, convertedValue);
> }
>
> protected override object GetBindValue(object value)
> {
> if(value == null) {
> return null;
> }
> return Convert.ChangeType(value, this.underlyingType);
> }
>
> protected override object GetValue(object value)
> {
> if(value == DBNull.Value) {
> return null;
> } else {
> return Enum.ToObject(this.enumType, value);
> }
> }
> }
> }
>
>
> = Seasar.Extension.ADO.ValueTypes.NullableEnumType
>
> using System;
> using System.Data;
>
> namespace Seasar.Extension.ADO.Types
> {
> public class NullableEnumType : NullableBaseType
> {
> private Type enumType;
> private Type underlyingType;
> private IValueType underlyingValueType;
>
> public NullableEnumType(Type enumType)
> {
> this.enumType = enumType;
> this.underlyingType = Enum.GetUnderlyingType(this.enumType);
> this.underlyingValueType = ValueTypes.GetValueType(this.underlyingType);
> }
>
> public override void BindValue(IDbCommand cmd, string columnName, object
> value)
> {
> object convertedValue = value == null ?
> null:
> Convert.ChangeType(value, this.underlyingType);
>
> this.underlyingValueType.BindValue(cmd, columnName, convertedValue);
> }
>
> protected override object GetBindValue(object value)
> {
> if(value == null) {
> return DBNull.Value;
> }
> return Convert.ChangeType(value, this.underlyingType);
> }
>
> protected override object GetValue(object value)
> {
> if(value == DBNull.Value) {
> return null;
> }
> return Enum.ToObject(this.enumType, value);
> }
> }
> }
>
>
>
> = Seasar.Extension.ADO.ValueTypes.ValueTypes
>
> // ValueTypes.GetValueTypeへの変更分です。
> public static IValueType GetValueType(Type type)
> {
> if(type == null) return OBJECT;
>
> IValueType valueType = GetValueType0(type);
> if(valueType != null)
> {
> return valueType;
> }
> else if(type.IsEnum)
> {
> return new EnumType(type);
> }
> #if !NET_1_1
> else if(IsNullableType(type))
> {
> Type nullableTType = GetNullableTType(type);
> if(nullableTType.IsEnum)
> {
> return new NullableEnumType(nullableTType);
> }
> }
> #endif
> return OBJECT;
> }
>
> #if !NET_1_1
> private static bool IsNullableType(Type type)
> {
> return type.IsGenericType &&
> type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
> }
>
> private static Type GetNullableTType(Type type)
> {
> return type.GetGenericArguments()[0];
> }
> #endif
>
>
> Nullableな列挙型へのマップ時に発生したエラーは下記のようになります。
>
> System.ArgumentException : 型 'System.Byte' のオブジェクトを型
> 'System.Nullable`1[列挙型]' に変換できません。
>
> 場所 System.RuntimeType.CheckValue(Object value, Binder binder,
> CultureInfo culture, BindingFlags invokeAttr)
> 場所 System.Reflection.MethodBase.CheckArguments(Object[] parameters,
> Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
> 場所 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
> invokeAttr, Binder binder, Object[] parameters, CultureInfo culture,
> Boolean skipVisibilityChecks)
> 場所 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
> invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
> 場所 System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object
> value, BindingFlags invokeAttr, Binder binder, Object[] index,
> CultureInfo culture)
> 場所 System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object
> value, Object[] index)
> 場所
> Seasar.Dao.Impl.AbstractBeanMetaDataDataReaderHandler.CreateRow(IDataReader
> reader, IColumnMetaData[] columns)
> 場所
> Seasar.Dao.Impl.BeanListMetaDataDataReaderHandler.Handle(IDataReader
> dataReader, IList list)
> 場所
> Seasar.Dao.Impl.BeanGenericListMetaDataDataReaderHandler.Handle(IDataReader
> dataReader)
> 場所 Seasar.Extension.ADO.Impl.BasicSelectHandler.Execute(IDbCommand cmd)
> 場所 Seasar.Extension.ADO.Impl.BasicSelectHandler.Execute(IDbConnection
> connection, Object[] args, Type[] argTypes)
> 場所 Seasar.Extension.ADO.Impl.BasicSelectHandler.Execute(Object[] args,
> Type[] argTypes)
> 場所 Seasar.Dao.Impl.SelectDynamicCommand.Execute(Object[] args)
> 場所 Seasar.Dao.Interceptors.S2DaoInterceptor.Invoke(IMethodInvocation
> invocation)
> 場所 Seasar.Framework.Aop.Proxy.AopProxy.Invoke(IMessage msg)
> 場所
> System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
> msgData, Int32 type)
>
> 以上よろしくお願いします。
>
> --
> /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
> 株式会社アトラス
> 羽田 拓央
> mail:   t_hada @ atlascorp.co.jp
> /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
>
>
> _______________________________________________
> seasar-dotnet mailing list
> seasar-dotnet @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>


-- 
Kazuya Sugimoto
http://d.hatena.ne.jp/sugimotokazuya/


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