【问题标题】:Does PetaPoco handle enums?PetaPoco 是否处理枚举?
【发布时间】:2011-10-14 14:13:41
【问题描述】:

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

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

public enum MyEnum
{
    Fred,
    Wilma
}

PetaPoco 在尝试将字符串“Fred”转换为 MyEnum 值时出现窒息。

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

Convert.ChangeType( src, dstType, null );

这里,src 是“Fred”(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 日更新

我不久前submitted a patch,但它还没有被拉进来。如果你想使用它,查看补丁并合并到你自己的代码中,或者直接获取代码from here

【问题讨论】:

  • 2012 年 6 月 28 日更新尚未应用确切的补丁,但在 v5 branch 中添加了类似的代码。另见toptensoftware.com/Articles/137/…
  • 如果对你来说不难,请把补丁也提交给 npoco。我建议您切换到 npoco,因为它的开发更加活跃,并且拥有 PetaPoco 拥有的所有功能,甚至更多。
  • 2014 年 9 月 9 日更新 @iano 答案是最新 5.0.2 版本的正确答案。

标签: orm petapoco


【解决方案1】:

我使用的是 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;
    }
}

【讨论】:

    【解决方案2】:

    你说得对,处理枚举不是 PetaPoco 内置的,通常我只是建议完全按照你的做法去做。

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

    【讨论】:

    • 谢谢布拉德。我将添加枚举查找并提交补丁。
    • 截至 2011 年 12 月 27 日,该补丁尚未应用。这将是一个很好的补充。
    • 2012 年 6 月 28 日更新尚未应用确切的补丁,但在 v5 branch 中添加了类似的代码。另见toptensoftware.com/Articles/137/…
    【解决方案3】:

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

    tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType";
    

    【讨论】:

      【解决方案4】:

      如果您想存储枚举的值而不是索引号(例如 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-10
        • 1970-01-01
        • 2020-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-20
        • 2022-10-21
        相关资源
        最近更新 更多