0

我有一个名为“Card”的类,其中包含“Sides”。

两个实体都有一个阶段 - 三个阶段之一。

这是我的Card实体:

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; }
}

这是我的Side实体:

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; } }
}

我注意到,当我创建一张新卡片或一面时,舞台表会获得一个标题为“ONE”和自动递增 ID 的新条目——这不应该发生。Stage 表中应该只有两个阶段。Stage 基本上是一个带有一些值的枚举——Title 和 Span。

如何防止添加新阶段?我正在使用 EF CodeFirst 以防万一。

更新基于 Honza 的回复:

public class Stage
{
    [Key]
    public virtual int StageId { get; set; }
    public string Name { get; set; }
    public TimeSpan Span { get; set; }

    public static class Values
    {
        public static readonly Stage ONE = new Stage()
            {
                StageId = 0,
                Name = "ONE",
                Span = new TimeSpan(0, 0, 0)
            };
        public static readonly Stage TWO = new Stage()
        {
            StageId = 1,
            Name = "TWO",
            Span = new TimeSpan(0, 0, 10)
        };
    }

它仍然是自动递增的——我错过了什么?

4

1 回答 1

0

每次实例化ONEandTWO时,它们都会在没有. 的情况下创建StageId。Entity Framework 需要一个提示来判断它们是否等于已经存在的 Stage 条目。在创建这些实例时制作密钥StageId并指定它。这样 EF 可以告诉他们已经在数据库中并引用现有的而不是创建新的。

这是一种非常“硬编码”的方法。

最好不要以这种方式创建实例,而是在数据库中查找它们(基于我猜的标题)并在它们不存在时创建它们。这样的操作可能不适合静态字段初始化,因为例如你得到一个 SQL 超时异常(数据库可能在另一台机器上,网络可能打嗝......),整个类型将无法加载,这是一个混乱的局面要处理。

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

于 2013-06-15T21:22:05.460 回答