Background: ho 200+ app legacy VB6 che sto convertendo in C #, usando EntityFramework Core come nostro ORM. Sfortunatamente molte app utilizzano la data zero di MySQL (0000-00-00)
. Quindi ho bisogno di tener conto di ciò ed essere in grado di memorizzare una data zero in qualche modo. Cambiare il modo fondamentale in cui funziona nelle oltre 200 app non è attualmente un'opzione.
Setup: posso definire una proprietà entity che rappresenta la definizione del campo in MySQL ad esempio:
public DateTime ExpiryDate { get; set; }
...
entity.Property(e => e.ExpiryDate)
.IsRequired()
.HasColumnType("datetime")
.HasDefaultValueSql("'0000-00-00 00:00:00'");
Questo memorizzerà correttamente una data zero se non viene inviato alcun valore su un inserto.
Problema: poiché C # ha una data minima di 0001-01-01
non è possibile memorizzare esplicitamente una data zero. Quindi la mia domanda è ... C'è un modo per impostare le mie entità per ottenere questa data zero dentro e fuori dal database ??
Finora: ho provato a utilizzare un campo di supporto, definito come una stringa in modo da poter manipolare qualsiasi DateTime.MinValue
per diventare '0000-00-00'
. Ciò mi consente di memorizzare la data zero ma causa un problema di trasmissione (come ci si aspetterebbe) durante il tentativo di recuperare i dati:
System.InvalidCastException: impossibile eseguire il cast dell'oggetto di tipo 'System.DateTime' per digitare 'System.String'.
I pacchetti correnti che sto usando sono:
La gente potrebbe obiettare che questo è più adatto come commento, ma in fondo, è troppo per questo.
E:
Dovrai aiutarmi un po 'perché non ho un sistema di lavoro a portata di mano, quindi lo sto facendo proprio in cima alla mia testa. (e sono un po 'di fretta)
Innanzitutto, inizia con una proprietà non mappata:
[NotMapped]
public DateTime ExpiryDate { get; set; }
Questa proprietà non è mappata. Potrebbe portare ad alcuni errori riguardanti il database che non corrisponde al modello, ma possiamo superarlo. Questa proprietà non verrà riempita automaticamente quando si interrogano i dati. Quindi, abbiamo bisogno di un modo per affrontare questo nostro sé.
Ad esempio, ( che è un cattivo esempio perché abbiamo bisogno del contesto nell'entità da qualche parte ):
[NotMapped]
public DateTime? ExpiryDate
{
get
{
//of course you'll need some caching here
var s = context.Database.SqlQuery<string>("query to select datetime as string");
//additional logic to determine validity:
if (s == "0000-00-00")
return null;
//else:
//do the conversion
}
}
La domanda di base qui; fino a che punto vuoi andare per sostenere questo all'interno del quadro EF? Hai solo bisogno di leggerlo, o scrivere pure, usando il change tracker di EF ecc.?
Esistono altre possibilità, ad esempio, di eseguire un'operazione CAST su nvarchar all'interno dello stesso SQL per ottenere i dati e elaborarli ulteriormente.
Forse ModelBuilder
espone alcune opzioni aggiuntive.