我正在尝试使用PetaPoco将表格转换为POCO。
在我的表中,我有一个名为TheEnum
的列。此列中的值是表示以下枚举的字符串:
public enum MyEnum
{
Fred,
Wilma
}
PetaPoco在尝试将字符串“Fred”转换为MyEnum
值时会窒息。
它在GetConverter
方法中的行中执行此操作:
Convert.ChangeType( src, dstType, null );
此处src
为“Fred”(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注册我的枚举?
2012年2月23日更新
我前一段时间submitted a patch但尚未被拉入。如果您想使用它,请查看补丁并合并到您自己的代码中,或只获取代码from here。
答案 0 :(得分:6)
我正在使用4.0.3,而PetaPoco会自动将枚举转换为整数并返回。但是,我想将我的枚举转换为字符串并返回。利用Steve Dunn's 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;
}
}
答案 1 :(得分:5)
你是对的,处理枚举并不是PetaPoco内置的,通常我只是建议你完成你所做的事情。
请注意,对于不使用枚举类型的请求,这不会减慢速度。 PetaPoco生成代码来映射对pocos的响应,因此只有在真正需要时才会调用委托。换句话说,只有在第一次使用特定的poco类型时才会调用GetConverter,并且只有在枚举需要转换时才会调用该委托。不确定Enum.Parse的速度,但是如果它太慢,你可以在字典中缓存。
答案 2 :(得分:5)
如果您正在使用PetaPoco的T4代,并且您希望在生成的类型中使用枚举,则可以在Database.tt中使用PropertyType覆盖:
tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType";
答案 3 :(得分: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