我正在尝试使用PetaPoco将表转换为POCO.
在我的表中,我有一个名为的列TheEnum.此列中的值是表示以下枚举的字符串:
public enum MyEnum
{
Fred,
Wilma
}
Run Code Online (Sandbox Code Playgroud)
当PetaPoco尝试将字符串"Fred"转换为MyEnum值时会发出ch咽声.
它在GetConverter方法中执行此操作,在行中:
Convert.ChangeType( src, dstType, null );
Run Code Online (Sandbox Code Playgroud)
这里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 ) ;
} ;
}
Run Code Online (Sandbox Code Playgroud)
显然,我不想在每一行都运行这个委托,因为它会大大减慢速度.我可以将这个枚举及其值注册到字典中以加快速度,但在我看来,这样的东西可能已经存在于产品中.
所以,我的问题是,我是否需要做一些特殊的事情来注册PetaPoco的枚举?
2012年2月23日更新
我正在使用4.0.3和PetaPoco自动将枚举转换为整数并返回.但是,我想将我的枚举转换为字符串并返回.利用Steve Dunn的EnumMapper和PetaPoco IMapper,我想出了这个.多谢你们.
请注意,它不处理Nullable<TEnum>DB中的值或为空值.要使用它,请设置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;
}
}
Run Code Online (Sandbox Code Playgroud)
你是对的,处理枚举不是内置于PetaPoco中,通常我只是建议你完成你所做的事情.
请注意,对于不使用枚举类型的请求,这不会减慢速度.PetaPoco生成代码以映射对pocos的响应,因此只有在真正需要时才会调用委托.换句话说,只有在第一次使用特定的poco类型时才会调用GetConverter,并且只有在枚举需要转换时才会调用该委托.不确定Enum.Parse的速度,但是如果它太慢,你可以在字典中缓存.
如果您正在使用PetaPoco的T4代,并且您希望在生成的类型中使用枚举,则可以在Database.tt中使用PropertyType覆盖:
tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType";
Run Code Online (Sandbox Code Playgroud)