2

当没有出现循环参考时,是否有更好的设计?有问题吗?课程:

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 用于对某事进行统计,例如举重等训练。数量可以是可以用数字测量的东西,例如所用杠铃的重量(以千克为单位 - 单位存储在 Unit 类中)或重复次数。在这种情况下,Stat(举重)有两个 Quantities(重量,代表)。Hit 是 Stat 的一个事件(一次完成的举重训练)。一个 HitComponent 属于一个 Hit,它包含一个 Quantity 的数量。每个 Hit 必须包含与 Hit 的 Stat 一样多的 HitComponent 和 Quantities。(例如,每个“举重”统计的 Hit 必须包含两个 HitComponent,一个用于“重量”数量,一个用于“代表”数量。我怀疑,也许这个先决条件会导致一些问题......)

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

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

4

1 回答 1

1

循环引用并不是那么邪恶。如果你看,你的引用只是虚拟的(你的 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; }
}
于 2013-08-31T17:30:01.973 回答