我有一个名为“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; }
}
这是我的 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; } }
}
我注意到当我创建一个新的Card或Side时,Stage表会获得一个标题为“ONE”的新条目和一个自动递增的ID - 这不应该发生。 Stage表中应该只有两个阶段。舞台基本上是一个带有一些值的枚举 - 标题和跨度。
如何防止添加新阶段?我正在使用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)
};
}
虽然它仍在自动增加 - 我缺少什么?
答案 0 :(得分:0)
每次实例化ONE
和TWO
时,都会在没有StageId
的情况下创建它们。实体框架需要提示能够告诉它们与已存在的Stage条目相等。设为StageId
密钥,在创建这些实例时指定。这样,EF可以告诉他们已经在数据库中并引用现有的而不是创建新的。
这是一种非常“硬编码”的方法。
可能更好,而不是以这种方式创建实例,在DB中查找它们(基于我猜的标题),如果它们不存在则创建它们。这样的操作可能不适合静态字段初始化,因为它例如你得到一个SQL超时异常(DB可能在另一台机器上,网络可能打嗝......),整个类型将无法加载,这是一个处理凌乱的情况。
您可以将实例保存在使用Stages的对象中,而不是静态字段。这将使与DB相关的作业和错误handlind更容易,并允许更好的可测试性(您可以使用ONE
和TWO
的任何实例,而不是硬编码的实例。