Come posso implementare il modello enum typesafe nel core rc2 di framework di entità?
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 dell'id è impostata in 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 (suppongo che ciò sia dovuto al setter privato). Quando si tenta di assegnare il valore enesa 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é è già stata tracciata un'altra istanza di questo tipo con la stessa chiave. Per le nuove entità prendere in considerazione 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 cercando di creare una nuova istanza con lo stesso ID. Come posso dire a EF che questi casi dovrebbero essere considerati uguali? Posso ovviare a questo allontanandomi dal modello enum typesafe. Vorrei solo farlo funzionare con il modello, se possibile. Funzionava 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.