どのようにエンティティフレームワークのコアrc2でtypesafe enumパターンを実装する

.net c# entity-framework entity-framework-core enums

質問

エンティティフレームワークコアrc2でtypesafe enumパターンを実装するにはどうすればよいですか?

public class TestStatus
{
    [Column("Id")]
    public int Id { get; private set; }

    [Column("Description")]
    public string Description { get; private set; }

    [Column("LongDescription")]
    public string LongDescription { get; private set; }

    private TestStatus(int id
        , string description
        , string longDescription)
    {
        Id = id;
        Description = description;
        LongDescription = longDescription;
    }

    public TestStatus() { }

    public static readonly TestStatus Active = new TestStatus(1, "Active", "Active Long Description");
    public static readonly TestStatus Pending = new TestStatus(2, "Pending", "Pending Long Description");
    public static readonly TestStatus Cancelled = new TestStatus(3, "Cancelled", "Cancelled Long Description");
}

id生成戦略は、OnModelCreatingで設定されます。

builder.Entity<TestStatus>()
    .Property(s => s.Id)
    .ValueGeneratedNever();

これは簡単な例ですが、実際のコードはrc1で動作していました。 rc2にアップグレードするときに、プロパティをマップするようにColumn属性を追加する必要がありました(私はこれがプライベートセッターのためであると想定しています)。型保証されたenum値を代入しようとすると、次のようになります。

var i = new TestItem
{
    Name = "Test Item 2",
    Status = TestStatus.Active
};
_context.Items.Add(i);
_context.SaveChanges();

私はユースケースに応じて次のエラーの1つを取得します。

InvalidOperationException:エンティティタイプ 'TestStatus'のインスタンスは、同じキーを持つこのタイプの別のインスタンスがすでに追跡されているため、追跡できません。新しいエンティティについては、IIdentityGeneratorを使用して一意のキー値を生成することを検討してください。

または

SqlException:PRIMARY KEY制約 'PK_Statuses'の違反です。オブジェクト 'dbo.Statuses'に重複キーを挿入できません。重複キー値は(1)です。ステートメントは終了されました。

私はエラーを理解しています。 EFは同じIdで新しいインスタンスを作成しようとしていると考えています。これらのインスタンスを同じとみなす必要があることをEFにどのように伝えることができますか?私はtypesafe enumパターンから離れることでこれを回避することができます。可能であれば、パターンと一緒に動作させたいのです。それはrc1で働いていた。

人気のある回答

タイプセーフなパターンを使用しているので、オブジェクト全体を永続化する必要はありません。 idを格納してラッパーを作成するだけです:

    [Required]
    protected string ObjectTypeValue { get; set; }

    [NotMapped]
    public ObjectType Type
    {
        get { return ObjectType.Parse(ObjectTypeValue); }
        set { ObjectTypeValue = value.Print(); }
    }

何らかの理由で私はIDとして文字列を使用しますが、好きなタイプを使用できます。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ