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 は、重量挙げなどのトレーニング エクササイズなど、何かの統計用です。Quantity は、使用したバーベルの重量 (キログラム単位 - 単位は Unit クラスに格納されています)、または繰り返し回数など、数値で測定できるものにすることができます。この場合、Stat (重量挙げ) には 2 つの数量 (重量、担当者) があります。ヒットは Stat の 1 つのイベントです (1 回の重量挙げトレーニング)。HitComponent は Hit に属し、1 つの Quantity の量を含みます。すべての Hit には、Hit の Stat が持つ Quantities と同じ数の HitComponent が含まれている必要があります。(たとえば、すべての「ウェイトリフティング」統計のヒットには、2 つの HitComponents が含まれている必要があります。1 つは「ウェイト」量用、もう 1 つは「担当者」量用です。おそらく、この前提条件が何らかの問題を引き起こす可能性があると思います...)

私は上記のデザインを使用しましたが、いくつかのクラスを Json 文字列にシリアライズしたい限り、循環参照例外が発生したため、あまり問題はありませんでした。

私の最初の質問は、この設計に何か問題があるということですか? 私はよくグーグル検索しましたが、この種の循環参照に対する明確で定義された答えが見つかりませんでした(方向が「循環」ではないため、実際の循環参照ではないと言う人もいれば、この解決策は非常に問題があると言う人もいます) ? 他の質問は、誰かがより良いデザインを提案できるかということです?

4

1 に答える 1

1

循環参照はそれほど悪いものではありません。見てみると、参照は単なる仮想です(リストも仮想である必要があります)ので、実際には、どちらの方向にも参照をたどる機能を予約する方向に沿っています。これがEFの定義または設計によって「循環参照」を作成することは、単なる副作用です。

これらの循環参照で問題が発生するのは、両方のナビゲーション プロパティを含むオブジェクトをシリアル化しようとするときだけです。この場合、循環参照を削除するために、ナビゲーション方向の 1 つをスキップするようシリアライザーに指示する必要があります。

シリアライザーによっては、ナビゲーション プロパティを無視する方法が異なります。Json(var) を使用する際に使用するバニラ シリアライザー (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 に答える