18

我正在尝试使用 PetaPoco 将表格转换为 POCO。

在我的表中,我有一个名为TheEnum. 此列中的值是表示以下枚举的字符串:

public enum MyEnum
{
    Fred,
    Wilma
}

当 PetaPoco 试图将字符串“Fred”转换为一个MyEnum值时,它会窒息。

它在GetConverter方法中执行此操作,在行中:

Convert.ChangeType( src, dstType, null );

在这里,src是 "Fred" (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>数据库中的值或空值。要使用它,请设置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 内置的,通常我只是建议完全按照你所做的事情去做。

请注意,对于不使用枚举类型的请求,这不会减慢速度。PetaPoco 生成代码以将响应映射到 pocos,因此只有在真正需要时才会调用委托。换句话说,GetConverter 只会在第一次使用特定的 poco 类型时被调用,而委托只会在枚举需要转换时被调用。不确定 Enum.Parse 的速度,但是如果速度太慢,您可以将其缓存在字典中。

于 2011-07-27T23:18:32.343 回答
5

如果您使用的是 PetaPoco 的 T4 代,并且您希望生成的类型中有枚举,则可以使用 Database.tt 中的 PropertyType 覆盖:

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

我想存储枚举的值而不是索引号(例如 1、2、4),您可以在 PetaPoco 类中找到更新函数,因为代码是“托管”等,当您将其添加为 nuget 包时将 .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 回答