如何使用单例类替换C#中的枚举?

如何使用单例类替换C#中的枚举?,c#,.net,entity-framework,ef-code-first,C#,.net,Entity Framework,Ef Code First,我有一个名为“Card”的类,它包含“Sides” 两个实体都有一个阶段——三个阶段中的一个 这是我的卡实体: public class Card { public Card() { Sides = new Collection<Side>(); Stage = Stage.ONE; } [Key] [Required] public virtual int CardId { get; set; }

我有一个名为“Card”的类,它包含“Sides”

两个实体都有一个阶段——三个阶段中的一个

这是我的实体:

public class Card
{
    public Card()
    {
        Sides = new Collection<Side>();
        Stage = Stage.ONE;
    }

    [Key]
    [Required]
    public virtual int CardId { get; set; }

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    [ForeignKey("CardId")]
    public virtual ICollection<Side> Sides { get; set; }
}
public class Side
{
    public Side()
    {
        Stage = Stage.ONE;
    }

    [Key]
    [Required]     
    public virtual int SideId { get; set; } 

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    public int CardId { get; set; }

    [ForeignKey("CardId")]
    public virtual Card Card { get; set; }

}
public class Stage
{
    // Zero
    public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
    // Ten seconds
    public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");

    public static IEnumerable<Stage> Values
    {
        get
        {
            yield return ONE;
            yield return TWO;
        }

    }

    public int StageId { get; set; }
    private readonly TimeSpan span;
    public string Title { get; set; }

    Stage(TimeSpan span, string title)
    {
        this.span = span;
        this.Title = title;
    }

    public TimeSpan Span { get { return span; } }
}
这是我的舞台实体:

public class Card
{
    public Card()
    {
        Sides = new Collection<Side>();
        Stage = Stage.ONE;
    }

    [Key]
    [Required]
    public virtual int CardId { get; set; }

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    [ForeignKey("CardId")]
    public virtual ICollection<Side> Sides { get; set; }
}
public class Side
{
    public Side()
    {
        Stage = Stage.ONE;
    }

    [Key]
    [Required]     
    public virtual int SideId { get; set; } 

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    public int CardId { get; set; }

    [ForeignKey("CardId")]
    public virtual Card Card { get; set; }

}
public class Stage
{
    // Zero
    public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
    // Ten seconds
    public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");

    public static IEnumerable<Stage> Values
    {
        get
        {
            yield return ONE;
            yield return TWO;
        }

    }

    public int StageId { get; set; }
    private readonly TimeSpan span;
    public string Title { get; set; }

    Stage(TimeSpan span, string title)
    {
        this.span = span;
        this.Title = title;
    }

    public TimeSpan Span { get { return span; } }
}

但它仍然是自动递增的-我缺少什么?

每次实例化
1
2
,它们都是在没有
StageId的情况下创建的。实体框架需要一个提示,以便能够判断它们是否等于已经存在的阶段条目。将
StageId
设为键,并在创建这些实例时指定它。这样EF就可以知道它们已经在数据库中,并引用现有的,而不是创建新的

不过,这是一种非常“硬编码”的方法

与其以这种方式创建实例,不如在DB中查找它们(基于我猜的标题),并在它们不存在时创建它们。但是,这样的操作可能不适合静态字段初始化,因为如果您遇到SQL超时异常(DB可能在另一台机器上,网络可能会打嗝…),整个类型将无法加载,这是一个需要处理的混乱情况


您可以不使用静态字段,而只保留使用stage的对象中的实例。这将使数据库相关作业和错误处理更容易,并允许更好的可测试性(您可以使用任何实例,如
ONE
TWO
,而不是硬编码的实例)。

谢谢Honza。我刚刚将[Key]添加到StageId并指定了id,但是它仍然在发生。我现在就用新代码更新我的帖子。知道我还需要做什么吗?更改是否反映在数据库本身中?我还没有开始那么多地使用代码。看起来是这样。。。我刚刚再次运行了迁移,可以看到更改。我创建了三张新卡,并看到了Stage One的三个实例:/EF可能需要另一个提示来使用
ForeignKey(“StageId”)
属性装饰
Card.Stage
属性。不过我只是在猜测,我现在不能亲自尝试,对不起。