PetaPoco обрабатывает перечисления? - PullRequest
18 голосов
/ 27 июля 2011

Я экспериментирую с PetaPoco для преобразования таблицы в POCO.

В моей таблице есть столбец с именем TheEnum.Значения в этом столбце являются строками, представляющими следующее перечисление:

public enum MyEnum
{
    Fred,
    Wilma
}

Дроссели PetaPoco при попытке преобразовать строку "Fred" в значение MyEnum.

Это делает этов методе GetConverter в строке:

Convert.ChangeType( src, dstType, null );

Здесь src - это "Фред" (a string), а dstType - это typeof(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?

Обновление 23 февраля 2012

Я недавно выпустил патч , но он не былподъехал еще.Если вы хотите использовать его, посмотрите на патч и объединитесь с вашим собственным кодом или получите код отсюда .

Ответы [ 4 ]

6 голосов
/ 07 апреля 2012

Я использую 4.0.3, и PetaPoco автоматически конвертирует перечисления в целые числа и обратно.Тем не менее, я хотел преобразовать мои перечисления в строки и обратно.Воспользовавшись EnumMapper Стива Данна и PetaPoco IMapper, я придумал это.Спасибо, ребята.

Обратите внимание, что он не обрабатывает Nullable<TEnum> или нулевые значения в БД.Чтобы использовать его, установите 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;
    }
}
5 голосов
/ 12 апреля 2012

Если вы используете генерацию T4 PetaPoco и хотите, чтобы в вашем сгенерированном типе были перечислены, вы можете использовать переопределение PropertyType в Database.tt:

tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType";
5 голосов
/ 28 июля 2011

Вы правы, обработка перечислений не встроена в PetaPoco, и обычно я просто предлагаю делать именно то, что вы сделали.

Обратите внимание, что это не замедлит работу для запросов, которые не используюттип перечисления.PetaPoco генерирует код для сопоставления ответов на pocos, поэтому делегат будет вызываться только тогда, когда это действительно необходимо.Другими словами, GetConverter будет вызываться только при первом использовании определенного типа poco, а делегат будет вызываться только тогда, когда enum нуждается в преобразовании.Не уверен в скорости Enum.Parse, но да, вы можете кэшировать в словаре, если он слишком медленный.

0 голосов
/ 05 июня 2015

Если вы хотите сохранить значение перечисления вместо номера индекса (например, 1,2,4), вы можете найти функцию обновления в классе PetaPoco, потому что код «управляемый» и т. Д., Когда вы добавляете его какПакет nuget будет хранить файл .cs для вашего проекта.Если бы у нас была переменная enum 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

...