【问题标题】:Using an enum as a primary key with EF使用枚举作为 EF 的主键
【发布时间】:2016-06-02 15:52:00
【问题描述】:

是否可以使用枚举作为表的主键?我有类似以下内容:

public enum SpecialId : uint {}

public class Thing 
{
     public SpecialId Id { get; set; }
}

public class MyContext : DbContext
{
     public DbSet<Thing> Things { get; set; }
}

但我在初始化时收到以下错误:

EntityFramework.dll 中出现“System.InvalidOperationException”类型的未经处理的异常

附加信息:关键组件“Id”不是“Thing”类型的声明属性。验证它没有被明确地从模型中排除,并且它是一个有效的原始属性。

这确实表明它需要是一个原始类型(枚举只能转换为原始类型),但 EF post around enums 建议这是可能的

枚举作为键

此外,枚举类型的属性可以参与主键、唯一约束和外键的定义,也可以参与并发控制检查,并声明了默认值。

是我做错了什么还是根本不支持?

另一方面,我不知道我可以使用另一个未映射的属性来破解此功能,以将键转换为枚举。这不是我正在寻找的答案

【问题讨论】:

  • 您是否考虑过添加Key 属性?还有什么版本的EF?
  • 是的,这没有帮助(例如HasKey(x=&gt;x.Id))无论如何,EF 应该按照惯例选择这个,但我确实尝试过这个,看看是否是问题
  • 你是先写代码???
  • 是,但在现有数据库上
  • 它们可以作为主键的一部分,而不是作为唯一的主键。

标签: c# entity-framework


【解决方案1】:

这不起作用,因为您的枚举基于 uint。 EF 通常不支持无符号整数类型(即您可以将 uint 类型用于属性),因此它也不适用于枚举属性。

我个人不是枚举键的忠实粉丝。这只是几个原因:

  • 数据库中的值很容易与您的枚举定义不同步
  • 如果数据库生成密钥,这可以打破常规 - 通常数据库从 1 开始生成 ID,但第一个枚举成员是 0
  • 枚举类型通常只有几个常量/成员。虽然可能有值在枚举基础类型的范围内,但在枚举类型中没有对应的常量(EF 支持这一点),但这违背了使用枚举类型的目的

【讨论】:

  • 太棒了,这解决了这个问题。我明白你所说的关于枚举作为键的内容,我完全同意。我的用例是我想要一个与数据库中的另一个实体有 1:* 关系的枚举。枚举表在应用程序启动时更新代码中的实际枚举,并删除任何不存在的枚举。我考虑过为此使用一个完全独立的密钥,但如果我直接从枚举中播种数据,我认为它实际上不会给我带来任何好处。
  • 没关系。与所有事情一样 - 如果您了解事情的运作方式以及限制和风险是什么,那么您应该可以很好地推动它。
  • 是的,底层主体拥有单一规范的数据源。在这种情况下,代码是规范源,但我想以特定方式在数据库中引用它。当您尝试通过拥有可以在代码或应用程序中创建的东西来混合规范来源时,您最终会遇到问题。
【解决方案2】:

看起来问题出在enum 基础类型上。

我没有找到任何信息,但是快速测试表明支持以下类型

byte, short, int, long

以下不是

sbyte, ushort, uint, ulong

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-29
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多