How to implement typesafe enum pattern in entity framework core rc2

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

Question

How can I implement the typesafe enum pattern in entity framework core rc2?

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

The id generation strategy is set in OnModelCreating:

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

This is a simplified example, but the real code was working in rc1. When upgrading to rc2, I had to add the Column attributes so that the properties would be mapped (I assume this is because of the private setter). When attempting to assign the typesafe enum value:

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

I get one of the following errors depending on the use case:

InvalidOperationException: The instance of entity type 'TestStatus' cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values.

Or

SqlException: Violation of PRIMARY KEY constraint 'PK_Statuses'. Cannot insert duplicate key in object 'dbo.Statuses'. The duplicate key value is (1). The statement has been terminated.

I understand the error. EF thinks that I am trying to create a new instance with the same Id. How can I tell EF that these instances should be considered the same? I can workaround this by moving away from the typesafe enum pattern. I would just like to make it work with the pattern if possible. It was working in rc1.

1
6
5/27/2016 1:16:03 PM

Popular Answer

Since you are using the Type-Safe Pattern there is no need to persist the whole object. Simply store the id and create a wrapper like so:

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

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

For some reasons I use a string as an Id, but you can use any type you like.

5
8/11/2016 11:44:38 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow