使用类/数据库的循环引用(C#,实体框架代码优先)

时间:2013-08-31 17:23:23

标签: c# entity-framework database-design ef-code-first circular-reference

当没有圆形引用时,是否有更好的设计?这根本不是问题吗? 课程:

public class Stat
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public List<Quantity> Quantities { get; set; }
    public List<Hit> Hits { get; set; }
}
public class Hit
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string Comment { get; set; }

    public virtual Stat Stat { get; set; }
    public List<HitComponent> HitComponents { get; set; }
}
public class HitComponent
{
    public int Id { get; set; }
    public float Amount { get; set; }

    public virtual Hit Hit { get; set; }
    public virtual Quantity Quantity { get; set; }
}
public class Quantity
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual Stat Stat { get; set; }
    public virtual Unit Unit { get; set; }
    public List<HitComponent> HitComponents { get; set; }
}
public class Unit
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }

    public List<Quantity> Quantities { get; set; }
}

Class diagram 统计数据用于统计某些事物,例如举重训练。数量可以是一个可以用数字来衡量的东西,例如所用杠铃的重量(以千克为单位 - 单位存储在单位类别中),或重复次数。在这种情况下,Stat(举重)有两个数量(重量,代表)。命中是Stat的一个事件(一次举重训练)。 HitComponent属于Hit,它包含一个Quantity的数量。每次命中都必须包含HitComponent所拥有的HitComponent数量。 (例如,每个“举重”Stat的命中必须包含两个HitComponents,一个用于“重量”数量,一个用于“reps”数量。我怀疑,这个先决条件可能会导致一些问题......)

我使用上面显示的设计,并没有太多问题 - 只是有点尴尬的循环引用 - 只要我想将一些类序列化为Json字符串,因为它导致循环引用异常。

我的第一个问题是这个设计有什么问题吗?我google了很多,并没有找到这种循环引用的清晰明确的答案(有人说它不是一个真正的循环引用,因为方向不是“循环”,其他人说这个解决方案很成问题) ? 另一个问题是,有人可以建议更好的设计吗?

1 个答案:

答案 0 :(得分:0)

循环引用不是那么邪恶。如果你看,你的引用只是虚拟的(你的List也应该是虚拟的)所以它更像是保留了在任一方向上遵循引用的能力。这通过EF的定义或设计创建了“循环引用”只是一种副作用。

当您尝试序列化包含两个导航属性的对象时,您唯一会遇到这些循环引用的问题。在这种情况下,您必须指示序列化程序跳过其中一个导航方向,以便删除循环引用。

根据序列化程序的不同,忽略导航属性将以不同方式完成。使用在使用Json(var)时使用的vanilla序列化程序(JavaScriptSerializer),您可以在属性中使用[ScriptIgnore]属性,在序列化期间不希望使用该属性。

例如,要删除从Stat到Hit

的循环引用
public class Stat
{
 public int Id { get; set; }
 public string Name { get; set; }
 public string Description { get; set; }

 public virtual List<Quantity> Quantities { get; set; }
 [ScriptIgnore]
 public virtual List<Hit> Hits { get; set; }
}