Come posso implementare il pattern enume tipizzato nell'entità 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");
}
La strategia di generazione id è impostata su OnModelCreating:
builder.Entity<TestStatus>()
.Property(s => s.Id)
.ValueGeneratedNever();
Questo è un esempio semplificato, ma il codice reale funzionava in rc1. Durante l'aggiornamento a rc2, ho dovuto aggiungere gli attributi Column in modo che le proprietà fossero mappate (presumo che ciò sia dovuto al setter privato). Quando si tenta di assegnare il valore enume typesafe:
var i = new TestItem
{
Name = "Test Item 2",
Status = TestStatus.Active
};
_context.Items.Add(i);
_context.SaveChanges();
Ottengo uno dei seguenti errori a seconda del caso d'uso:
InvalidOperationException: l'istanza del tipo di entità "TestStatus" non può essere tracciata perché un'altra traccia di questo tipo con la stessa chiave è già stata tracciata. Per le nuove entità considerare l'utilizzo di un IIdentityGenerator per generare valori chiave univoci.
O
SqlException: violazione del vincolo PRIMARY KEY "PK_Statuses". Impossibile inserire la chiave duplicata nell'oggetto "dbo.Statuses". Il valore della chiave duplicata è (1). La dichiarazione è stata chiusa.
Capisco l'errore. EF pensa che sto provando a creare una nuova istanza con lo stesso Id. Come posso dire a EF che queste istanze dovrebbero essere considerate uguali? Posso aggirare questo allontanandomi dal pattern enume tipizzato. Vorrei solo farlo funzionare con il modello, se possibile. Stava lavorando in RC1.
Dal momento che stai usando il Pattern Type-Safe non è necessario mantenere l'intero oggetto. Basta memorizzare l'id e creare un wrapper in questo modo:
[Required]
protected string ObjectTypeValue { get; set; }
[NotMapped]
public ObjectType Type
{
get { return ObjectType.Parse(ObjectTypeValue); }
set { ObjectTypeValue = value.Print(); }
}
Per alcuni motivi, utilizzo una stringa come ID, ma puoi usare qualsiasi tipo che ti piace.