当没有圆形引用时,是否有更好的设计?这根本不是问题吗? 课程:
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; }
}
统计数据用于统计某些事物,例如举重训练。数量可以是一个可以用数字来衡量的东西,例如所用杠铃的重量(以千克为单位 - 单位存储在单位类别中),或重复次数。在这种情况下,Stat(举重)有两个数量(重量,代表)。命中是Stat的一个事件(一次举重训练)。 HitComponent属于Hit,它包含一个Quantity的数量。每次命中都必须包含HitComponent所拥有的HitComponent数量。 (例如,每个“举重”Stat的命中必须包含两个HitComponents,一个用于“重量”数量,一个用于“reps”数量。我怀疑,这个先决条件可能会导致一些问题......)
我使用上面显示的设计,并没有太多问题 - 只是有点尴尬的循环引用 - 只要我想将一些类序列化为Json字符串,因为它导致循环引用异常。
我的第一个问题是这个设计有什么问题吗?我google了很多,并没有找到这种循环引用的清晰明确的答案(有人说它不是一个真正的循环引用,因为方向不是“循环”,其他人说这个解决方案很成问题) ? 另一个问题是,有人可以建议更好的设计吗?
答案 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; }
}