【问题标题】:Should the EnumDataTypeAttribute work correctly in .NET 4.0 using Entity Framework?EnumDataTypeAttribute 是否应该在使用实体框架的 .NET 4.0 中正常工作?
【发布时间】:2026-01-27 23:30:01
【问题描述】:

我有一个枚举,我想将它作为某种值持久保存到底层数据库中,以便我可以来回调用它。

我阅读了一些文章,建议创建一个枚举包装器,其中定义了静态隐式运算符,使用 ComplexType 对象映射进行映射,如下面的链接所述。

How to fake Enums in EF4

此解决方案完美无缺!感谢Alex James

除此之外,我发现EnumDataTypeAttribute Class 的目的似乎是通过实体框架处理枚举持久性。我试过了,它似乎根本不起作用。这是一个代码示例。

public enum StreetDirection {
    East
    , None
    , North
    , NorthEast
    , NorthWest
    , South
    , SouthEast
    , SouthWest
    , West
}

public enum StreetType {
    Avenue
    , Boulevard
    , Court
    , Crescent
    , Drive
    , Hill
    , None
    , Road
    , Street
}

public class StreetTypeWrapper {
    public int Value {
        get {
            return (int)t;
        } 
        set {
            t = (StreetType)value;
        }
    }
    public StreetType EnumValue {
        get {
            return t;
        } 
        set {
            t = value;
        }
    }

    public static implicit operator int(StreetTypeWrapper w) {
        return w.Value;
    }

    public static implicit operator StreetType(StreetTypeWrapper w) {
        return w == null ? StreetType.None : w.EnumValue;
    }

    public static implicit operator StreetTypeWrapper(int i) {
        return new StreetTypeWrapper() { Value = i };
    }

    public static implicit operator StreetTypeWrapper(StreetType t) {
        return new StreetTypeWrapper() { EnumValue = t };
    }

    private StreetType t;
}

public class Street {
    [EnumDataType(typeof(StreetDirection))]
    public StreetDirection Direction { get; set; }
    public string Name { get; set; }
    public int StreetId { get; set; }
    public StreetTypeWrapper Type { get; set; }
}

public class StreetTypeMapping 
    : ComplexTypeConfiguration<StreetTypeWrapper> {
    public StreetTypeMapping() {
        Property(o => o.Value)
            .HasColumnName("StreetType");
    }
}

现在,如果我相信和/或正确理解 MSDN 关于 EnumDataTypeAttribute 类的说法,Direction 属性应该被持久化到数据库中。好吧,它没有!我找不到原因,除了 EF 不支持枚举持久性。至于StreetTypeWrapper 和它的StreetTypeMapping 类,它确实可以完美运行。

是否有任何线索说明 EnumDataType 不能按预期工作?

【问题讨论】:

  • 确定吗?我没有在 Alex James 的帖子中看到 ComplexType 映射。我按照您的模板进行操作,在添加迁移期间出现错误,提示自定义包装器(即 StreetTypeWrapper)没有定义键。即使我在模型/上下文中没有 DbSet<...wrapper> 似乎认为包装器也是一个实体。

标签: entity-framework-4 attributes enums persistence wrapper


【解决方案1】:

这是因为 .NET 框架的设计缺陷。 .NET 框架包含著名的System.ComponentModel.DataAnnotations 命名空间,其中定义了多个不同的属性。 .NET 框架的许多不同部分都在使用这个命名空间,但它们使用它来完成不同的任务,并且每个这样的部分只使用一些属性子集。这会引起很多混乱。

EnumDataTypeAttribute 就是这样的例子。此属性仅适用于 ASP.NET 动态数据。它允许您使用此属性标记 int 属性,并且自动生成的 UI 将显示带有枚举值的下拉列表,而不是数值的文本框。所以存在从 enum 到 int 的映射,但它在 UI 层而不是在模型/持久层中。

【讨论】:

  • +1 感谢您的精彩解释。这就是为什么我不能以这种方式坚持我的枚举。无论如何,我更喜欢包装解决方法,因为没有这样的装饰器。尽管稍后在项目中,我将在 UI 上尝试它。谢谢! =)
  • +1 也感谢这个很好的解释,我昨天才知道,打算在模型类中使用它:)。