0

「サイド」を含む「カード」というクラスがあります。

両方のエンティティには、ステージ (3 つのステージのうちの 1 つ) があります。

ここに私のカードエンティティがあります:

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; }
}

これが私のサイドエンティティです:

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; }

}

そして、これが私のStageエンティティです:

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; } }
}

新しいカードまたはサイドを作成すると、ステージ テーブルに「ONE」のタイトルと自動インクリメント ID を持つ新しいエントリが作成されることに気付きましたが、これは発生すべきではありません。ステージ テーブルには 2 つのステージのみが存在する必要があります。Stage は基本的に、いくつかの値 (Title と Span) を持つ列挙型です。

新しいステージが追加されないようにするにはどうすればよいですか? 関連する場合に備えて、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)
        };
    }

それでも自動インクリメントです-何が欠けていますか?

4

1 に答える 1

0

ONEとをインスタンス化するたびに、.TWOなしで作成されStageIdます。Entity Framework は、それらが既存の Stage エントリと等しいことを伝えるためのヒントを必要とします。キーStageId作成し、それらのインスタンスを作成するときに指定します。そうすれば、EF はそれらが既に DB にあることを認識し、新しいものを作成する代わりに既存のものを参照できます。

ただし、これは非常に「ハードコードされた」アプローチです。

この方法でインスタンスを作成する代わりに、DB でそれらを探し (私が推測するタイトルに基づいて)、存在しない場合は作成する方がよい場合があります。ただし、このような操作は静的フィールドの初期化には適していない可能性があります。たとえば、SQL タイムアウト例外が発生した場合 (DB が別のマシンにある可能性がある、ネットワークが中断する可能性がある...)、型全体を読み込むことができず、それは対処する厄介な状況。

静的フィールドの代わりに、ステージを使用するオブジェクトにインスタンスを保持するだけです。これにより、DB 関連のジョブとエラー処理が容易になり、テスト容易性が向上します (ハードコーディングされたインスタンスではなく、ONEおよびとして任意のインスタンスを使用できます)。TWO

于 2013-06-15T21:22:05.460 に答える