Per i dati così semplici da calcolare, non ha senso memorizzare dati denormalizzati (tutti e tre).
Archivia solo i grammi e l'utente nel database, quindi carica le proprietà dell'utente e grammi di questo oggetto con i dati memorizzati.
public class Weight
{
public string User {get;set;}
public double Grams {get;set;}
public double KG
{
get { return Grams * .001; }
set { Grams = value * 1000.0;}
}
public double Pounds
{
get { return Grams * 0.00220462; }
set { Grams = value * 453.592; }
}
}
e per lo storage, possiamo vedere i vantaggi del pattern di repository per casi come questo in cui la nostra soluzione di archiviazione ottimale non assomiglia al nostro caso di utilizzo aziendale:
public class WeightRepository
{
public void Insert(Weight weight)
{
sqlConnection.Execute("insert into Weight (User, Grams) values (@user, @grams)", weight.User, weight.Grams);
}
//Get, update, ect
}
Con questo approccio, la nostra logica aziendale (classe di peso) è isolata, comoda da usare e facilmente testata da unità.
Possiamo anche ottenere letture veloci e brillanti dal nostro DB poiché abbiamo ridotto al minimo il nostro numero di colonne.
Di solito, una buona architettura aumenta le prestazioni, non la ostacola:)