实体框架 - 一般持久化枚举?

发布于 2024-12-23 08:30:36 字数 1200 浏览 5 评论 0原文

尝试创建一种使用泛型在实体框架中处理枚举的解决方法,但 EF 似乎并不关心泛型属性。例如:

public enum MyEnum
{
    One, Two, Three
}

public class SomePOCOWithEnum
{
      // I want this to persist as an int, but EF doesn't like generics.
      public EnumWrapper<MyEnum> MyEnumProperty { get; set; }
}

目的是让枚举作为 INT 保留在数据库中。是否有任何特殊的方法使用 Fluent 或其他机制方法,我可以创建所述泛型类并将其作为 INT 持久保存到 EF 中的数据库中?

目的是保持通用性,因为我有大约两打枚举需要持久化,而且我不想为每个枚举编写单独的包装类。

这是通用的 EnumWrapper 类,它演示了我想要完成的任务:隐式转换为枚举,但持久化为 int:

public class EnumWrapper<T> where T : struct
{
    private T enumValue;
    public int Value
    {
        get { return Convert.ToInt32(enumValue); }
        set { enumValue = (T)Enum.Parse(typeof(T), value.ToString()); }
    }

    public T EnumValue
    {
        get { return enumValue; }
        set { enumValue = value; }
    }

    public static implicit operator T(EnumWrapper<T> wt)
    {
        return wt.EnumValue;
    }

    public static implicit operator EnumWrapper<T>(T t)
    {
        return new EnumWrapper<T>() { EnumValue = t };
    }

    public override string ToString()
    {
        return enumValue.ToString();
    }
}

Trying to create a workaround for processing Enums in the Entity Framework using Generics, but EF doesn't seem to care for generic properties. For example:

public enum MyEnum
{
    One, Two, Three
}

public class SomePOCOWithEnum
{
      // I want this to persist as an int, but EF doesn't like generics.
      public EnumWrapper<MyEnum> MyEnumProperty { get; set; }
}

The intention is to have the enum persist as an INT in the database. Is there any special way using fluent or perhaps some other mechanism method whereby I can create said generic class and have it persist as an INT to the database within EF?

The intention is to keep things generic as I have about two dozen enums that need persisting, and I'd rather not write individual wrapper classes for each of them.

Here is the generic EnumWrapper class, which demonstrates what I'd like to accomplish: implicit conversion to enum, but persistence as an int:

public class EnumWrapper<T> where T : struct
{
    private T enumValue;
    public int Value
    {
        get { return Convert.ToInt32(enumValue); }
        set { enumValue = (T)Enum.Parse(typeof(T), value.ToString()); }
    }

    public T EnumValue
    {
        get { return enumValue; }
        set { enumValue = value; }
    }

    public static implicit operator T(EnumWrapper<T> wt)
    {
        return wt.EnumValue;
    }

    public static implicit operator EnumWrapper<T>(T t)
    {
        return new EnumWrapper<T>() { EnumValue = t };
    }

    public override string ToString()
    {
        return enumValue.ToString();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风蛊 2024-12-30 08:30:36

正如 sinelaw 已经指出的那样,EF5 明确支持 Enum,但如果您出于某种原因无法迁移到它,我采取的方法可能适合您。

对于此示例,假设该表名为“Email”,并且有一列名为“Priority”。像平常一样将列设置为 int。接下来,在您的实体项目中,创建一个映射到 int 值的枚举类:

public enum EmailPriorityEnum
{
    Now = 100,
    Soon = 1000,
    Whenever = 10000
}

最后,在您的实体项目中,创建一个与您的实体匹配的部分类文件,并在那里手动映射枚举:

public partial class Email
{
    public EmailEnums.EmailPriorityEnum EmailPriority
    {
        get { return (EmailEnums.EmailPriorityEnum)Priority; }
        set { Priority = (int)value; }
    }
}

从那里开始,您的代码可以引用此财产透明。这种方法的主要缺点是:

  1. 您必须小心,所有可能的值都使用正确的 id 映射到枚举中。对于经常改变的枚举来说,这会成为问题。
  2. 开发人员仍然可以访问底层列,除非您更改可访问性,并且可以绕过枚举并使用他们喜欢的任何值。

As sinelaw has already pointed out, EF5 has explicit support for Enums, but if you cannot migrate to it for whatever reason, the approach I've taken might work for you.

For this example, let's say the table is named "Email" and we have a column named "Priority". Setup your column as an int as you would normally do. Next, in your entities project, create an enums class that maps to your int values:

public enum EmailPriorityEnum
{
    Now = 100,
    Soon = 1000,
    Whenever = 10000
}

Finally, in your entities project, create a partial class file matching your entity and manually map the enum there:

public partial class Email
{
    public EmailEnums.EmailPriorityEnum EmailPriority
    {
        get { return (EmailEnums.EmailPriorityEnum)Priority; }
        set { Priority = (int)value; }
    }
}

From there on out, your code can reference this property transparently. The primary drawbacks to this approach are:

  1. You have to be careful that all possible values are mapped in the enum with the proper ids. For enums that change often this becomes problematic.
  2. Developers will still have access to the underlying column unless you change the accessibility and could conceivably bypass the enums and use whatever value they like.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文