【问题标题】:Mapping enum table to enum type in Entity Framework 1 (.NET 3.5) - Database first approach将枚举表映射到实体框架 1 (.NET 3.5) 中的枚举类型 - 数据库优先方法
【发布时间】:2013-11-29 15:26:31
【问题描述】:

假设您有两个表 - Orders 和 OrderStates - 并且每个 Order 都处于特定状态的明显关系。假设两者都有一个 int 主键 ID。订单状态永远不会改变,并且仅出于设计和用户界面目的而存储在数据库中。话虽如此,您将希望创建一个表示订单状态的 Enum 类型。但是,实体框架已经使用 order state int value/key 生成了类。

给定问题的可能解决方案是什么?请记住,如果您愿意,问题是关于 EF1 或 EF .NET 3.5,并且您从已经设计好的数据库开始(数据库优先方法)。我使用旧版本是因为我目前正在为 Sharepoint 2010 开发一个在 .NET 3.5 上运行的应用程序。

我只找到了 EF4 或更高版本的解决方案,例如: Enum Support for Entity Framework Database First

为了更清楚,我想避免一直转换 int。生成的代码强制您编写:

 (OrderStates)OrderState.State == OrderState.StateX;

 OrderState.State == (int)OrderState.StateX;

如果您只遇到一次这种情况可能没问题,但通常情况并非如此。枚举的代码可读性也高于一些 int 值。

【问题讨论】:

  • 我真的很困惑为什么你不能只建立一个enum。你已经说过桌子不会改变。
  • 我已经编辑了这个问题。我希望现在更清楚了。

标签: c# .net-3.5 operators operator-overloading


【解决方案1】:

好的,所以您不能在 enum 上重载运算符。但是,您可以构建一个 class 来重载您可以双向使用的运算符。考虑以下代码:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(1 == MyEnum.Value0);
        Console.WriteLine(2 == MyEnum.Value2);
    }
}

public class MyEnum
{
    public static readonly MyEnum Value0 = 0;
    public static readonly MyEnum Value1 = 1;
    public static readonly MyEnum Value2 = 2;

    private MyEnum() { }

    private int _val;
    private MyEnum(int val)
    {
        _val = val;
    }

    public static implicit operator int(MyEnum val)
    {
        return val._val;
    }

    public static implicit operator MyEnum(int val)
    {
        return new MyEnum(val);
    }
}

这个输出:

False
True

因此,如果您构建了一个名为 OrderStates 的类,它像我在此处所做的那样重载了运算符,然后列出了所有状态,那么您将有效地得到一个带有比较重载的 enum

【讨论】:

  • 这不是一个很好的解决方案。你必须为一个枚举写很多东西。
  • @Santhos,我从来没有声称它是优雅的。 我只是让你知道这是你所在位置的解决方法。 enum 类型不能被重载。此外,如果您检查了 EF 生成的代码是否符合您的要求,它实际上是在执行强制转换。只是代码是生成的,所以在这种情况下你不在乎。
  • 但这正是不同之处。如果演员表是在课堂上生成的,我会完全满意,因为我不必编写任何额外的代码,而且我会有漂亮的条件。我只是喜欢可读的代码。如果我想要丑陋的代码,我会手动编写演员表,这不是“什么大不了的事”。
  • @Santhos,作为枚举的类之外的代码看起来和你想要的一样干净。以你目前的态度,你的问题没有解决办法。由于您正在构建 SharePoint 插件,因此您无法使用特定的框架版本。对此,任何人都无能为力。此外,该语言的设计者出于某种原因没有实现这一点。你不想让一个有点痛苦的类而不是在你的代码中到处进行强制转换吗?
  • 可能是的。我仍然觉得使用泛型或其他东西可能会有更好的解决方案。我会考虑一下。我还发现可以简单地用枚举覆盖整数,并且代码生成不会将其覆盖回整数。但是,我必须先对其进行测试。
【解决方案2】:

一个简单的扩展方法应该会产生一些可读性很强的代码:

public static class OrderStatesExtensions
{
    public static bool Is(this int n, OrderStatesstate)
    {
        return (States) n == state;
    }

    public static bool Is(this OrderStates state, int n)
    {
        return n.Is(state);
    }
}

// usage
order.State.Is(OrderStates.Something)

不过,公平地说,我不确定它在发送到服务器时会如何工作;即,这可能仅在返回结果后才有用。

【讨论】:

  • +1,这是我在决定走哪条路时考虑过的另一个解决方案。我相信你是对的,它只会在客户端工作,但我不确定我的在这方面会有什么不同。
  • 当生成的类被完全标记为部分时,不需要创建扩展类。
【解决方案3】:

我使用过但这里没有提到的方法是我创建了 Order 的部分类(因为 EF 将类生成为部分类),然后我在那里放置了一个方法来进行强制转换。您必须在每个使用枚举或任何其他枚举的类中执行此操作。但是,无论如何,您必须自己定义这些枚举,至少它很干净。

public partial class Order
{
    public OrderState GetOrderState()
    {
        return (OrderState)this.OrderState.Id;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 2019-04-09
    相关资源
    最近更新 更多