Ho un database legacy che memorizza i commenti degli utenti (e molti altri campi di testo) come dati blob
, che non posso modificare.
Sto scrivendo un livello di accesso ai dati che dovrà sempre convertire i dati in una string
quando viene recuperato dal database e convertirlo nuovamente in blob
durante il salvataggio.
Lo strumento di ponteggio EF ha generato proprietà come tipo di dati byte[]
per queste entità.
public byte[] Comment { get; set; }
Ho notato che se cambio semplicemente il tipo di proprietà di entità in string
, in realtà salva i dati correttamente, ma il caricamento dei dati genera un errore di trasmissione:
Impossibile eseguire il cast dell'oggetto di tipo 'System.Byte []' per digitare 'System.String'.
(È interessante notare che la versione 1.0.0 non ha generato questo errore, il caricamento e il salvataggio hanno funzionato correttamente).
La mia domanda è ... Esiste un modo per configurare il core EF per convertire automaticamente questi dati in stringa quando li recupero dal database e tornano al blob
quando vengono salvati? O avrò bisogno di scrivere un gruppo di getter e setter privati per fare questa manipolazione?
Inoltre, per il mio commento sulla tua risposta, se non vuoi aggiungere getter e setter e vuoi avere un codice pulito, puoi anche lavorare con i metodi di estensione:
public static class Extensions
{
public static byte[] GetBytes(this string @this, System.Text.Encoding encoding = null)
{
return (encoding??Encoding.UTF8).GetBytes(@this);
}
public static string GetString(this byte[] @this, System.Text.Encoding encoding = null)
{
return (encoding??Encoding.UTF8).GetString(@this);
}
}
puoi lavorare con loro in questo modo:
myentity.Comment = "my comment".GetBytes();
string comment = myentity.Comment.GetString();
prenditi cura del valore di default nel codice, che è UTF8, puoi cambiarlo con la codifica che vuoi usare, o inserire un'altra codifica come
byte[] myBytes = "my comment".GetBytes(Encoding.ASCII);
la tua vittoria: non devi specificare un getter / setter per ogni proprietà usando il byte[]
La conversione del byte[]
in una string
richiede sempre una Encoding
. Dal momento che EF non sa quale codifica usare, tale conversione automatica non è possibile.
Ciò che puoi fare è contrassegnare la proprietà Comment come privata e creare una proprietà wrapper che converta il valore in una stringa con una Encoding
tua scelta:
partial class MyEntity
{
private string m_commentText = null;
public string CommentText
{
get {
if ((m_commentText == null) && (Comment != null)) {
m_commentText = Encoding.UTF8.GetString(Comment);
}
return m_commentText;
}
set {
m_commentText = value;
if (value != null) {
Comment = Encoding.UTF8.GetBytes(value);
}
else {
Comment = null;
}
}
}
}
Questa soluzione memorizza il testo in un campo backer per evitare più conversioni da byte[]
a string
. Se è necessario che la proprietà Comment
rimanga pubblica, è necessario rimuovere il campo backer per evitare l'incoerenza dei dati:
partial class MyEntity
{
public string CommentText
{
get {
if (Comment != null) {
return Encoding.UTF8.GetString(Comment);
}
else {
return null;
}
}
set {
if (value != null) {
Comment = Encoding.UTF8.GetBytes(value);
}
else {
Comment = null;
}
}
}
}