18

テーブルをPOCOに変換するためにPetaPocoを試しています。

私のテーブルには、という名前の列がありますTheEnum。この列の値は、次の列挙型を表す文字列です。

public enum MyEnum
{
    Fred,
    Wilma
}

文字列「Fred」を値に変換しようとすると、PetaPoco がチョークしMyEnumます。

GetConverterメソッドの次の行でこれを行います。

Convert.ChangeType( src, dstType, null );

ここで、srcは「フレッド」 (a string) であり、dstTypetypeof(MyEnum)です。

例外は、InvalidCastExceptionと言ってInvalid cast from 'System.String' to 'MyEnum'

何か不足していますか?最初に登録しなければならないものはありますか?

GetConverterメソッドに以下を追加することで問題を回避しました。

if (dstType.IsEnum && srcType == typeof(string))
{
  converter = delegate( object src )
            {
                return Enum.Parse( dstType, (string)src ) ;
            } ;
}

明らかに、このデリゲートをすべての行で実行したくはありません。処理が大幅に遅くなるからです。この列挙型とその値をディクショナリに登録して高速化することもできますが、このようなものが既に製品に組み込まれている可能性が高いと思われます。

それで、私の質問は、列挙型を PetaPoco に登録するために何か特別なことをする必要がありますか?

2012 年 2 月 23 日更新

しばらく前にパッチを提出しましたが、まだ取り込まれていません。使用したい場合は、パッチを見て自分のコードにマージするか、ここからコードだけを入手してください。

4

4 に答える 4

6

私は4.0.3を使用していますが、PetaPocoは列挙型を整数に自動的に変換します。ただし、列挙型を文字列に変換して戻したいと思いました。Steve DunnのEnumMapperとPetaPocoを利用IMapperして、これを思いつきました。みんなありがとう。

Nullable<TEnum>DB内の値またはnull値を処理しないことに注意してください。使用するには、PetaPoco.Database.Mapper = new MyMapper();

class MyMapper : PetaPoco.IMapper
{
    static EnumMapper enumMapper = new EnumMapper();

    public void GetTableInfo(Type t, PetaPoco.TableInfo ti)
    {
        // pass-through implementation
    }

    public bool MapPropertyToColumn(System.Reflection.PropertyInfo pi, ref string columnName, ref bool resultColumn)
    {
        // pass-through implementation
        return true;
    }

    public Func<object, object> GetFromDbConverter(System.Reflection.PropertyInfo pi, Type SourceType)
    {
        if (pi.PropertyType.IsEnum)
        {
            return dbObj =>
            {
                string dbString = dbObj.ToString();
                return enumMapper.EnumFromString(pi.PropertyType, dbString);
            };
        }

        return null;
    }

    public Func<object, object> GetToDbConverter(Type SourceType)
    {
        if (SourceType.IsEnum)
        {
            return enumVal =>
            {
                string enumString = enumMapper.StringFromEnum(enumVal);
                return enumString;
            };
        }

        return null;
    }
}
于 2012-04-06T20:11:50.773 に答える
5

PetaPoco の T4 世代を使用していて、生成された型に列挙型が必要な場合は、Database.tt で PropertyType オーバーライドを使用できます。

tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType";
于 2012-04-11T21:45:51.417 に答える
5

そうです、列挙型の処理は PetaPoco に組み込まれていません。通常は、あなたが行ったことを正確に実行することをお勧めします。

これにより、列挙型を使用しないリクエストの速度が低下しないことに注意してください。PetaPoco は、応答を poco にマップするコードを生成するため、本当に必要な場合にのみデリゲートが呼び出されます。つまり、GetConverter は特定の poco 型が初めて使用されるときにのみ呼び出され、デリゲートは列挙型の変換が必要な場合にのみ呼び出されます。Enum.Parse の速度についてはわかりませんが、遅すぎる場合は辞書にキャッシュできます。

于 2011-07-27T23:18:32.343 に答える
0

インデックス番号 (たとえば 1,2,4) の代わりに列挙型の値を保存したい場合は、nuget パッケージとして追加するときに、コードが「管理」されているため、PetaPoco クラスで更新関数を見つけることができます。 .cs ファイルをプロジェクトに保存します。列挙変数 Color = {red, yellow, blue} がある場合

それ以外の:

// Store the parameter in the command
AddParam(cmd, pc.GetValue(poco), pc.PropertyInfo);

への変更:

//enum?
if (i.Value.PropertyInfo.PropertyType.IsEnum)
{
       AddParam(cmd, i.Value.GetValue(poco).ToString(), i.Value.PropertyInfo);
}
else
{
       // Store the parameter in the command
       AddParam(cmd, i.Value.GetValue(poco), i.Value.PropertyInfo);
}

2の代わりに「黄色」を保存します

于 2015-06-05T15:28:23.740 に答える