-
Notifications
You must be signed in to change notification settings - Fork 386
Saving to database
There is currently no out-of-the-box solution for storing UnitsNet quantities and units in an SQL database, or any other database.
The main reason is that UnitsNet does occasionally need to do breaking changes on the unit definitions
- Rename or remove a quantity or a unit
- Change the unit abbreviations for a unit
It is not trivial to ensure backwards compatibility for these changes, for different types of databses and ORM frameworks. Handling it properly may involve storing the version of UnitsNet with the data, and having migration steps between versions.
From @lipchev:
- Using a single column for storing the
Value
of the quantity, converted to some base unit (e.g. storing all values asMassUnit.Gram
orVolumeUnit.Milliliter
)- this is probably the only option that can support direct database queries (anything else would require some form of aCASE
switching query on the set of applicable units). This option assumes that the UI is responsible for actually selecting an appropriate display unit for the quantity. - Using two columns mapped to the
{Value, Unit}
pair: this assumes that the user is expecting to see the quantity in the same unit as it was entered. The slight problem here is when dealing with the non-default abbreviations- if the UI supports the input of the quantity using all of the unit abbreviations, then you wouldn't be able to restore the exact quantity string (e.g. expecting "ts." instead of "tsp" for theMetricTeaspoon
). This is of course not a huge issue, but something to keep in mind when mapping custom abbreviations. - Using a single string-based column- the code for parsing a quantity from string is still very slow, I doubt it would beat option 2) (but would be curious to see a comparison).
From @angularsen:
I would personally do something along number 2, and serialize decimal Value
and string UnitName
similar to how we do JSON: https://github.com/angularsen/UnitsNet/wiki/Serializing-to-JSON,-XML-and-more
I would also, if I only used a few quantities and units, choose my own custom serialization format to avoid any breaking changes in names of UnitsNet, which do happen. Something like this:
IQuantity myQuantity = ...;
var myDbEntity = new MyDbEntity {
Value = myQuantity.Value,
UnitName = myQuantity switch {
LengthUnit.Meter => "Length:Meter",
LengthUnit.Centimeter => "Length:Centimeter",
MassUnit.Kilogram => "Mass:Kilogram",
// ... and any other units we want to support serializing
_ => throw new NotImplementedException("Unit not supported for serialization to SQL: " + myQuantity.Unit);
}
};
You would then have to parse it back out with a simple string.Split
and similar switch conditions.
It's a boring one time job, but then you are in full control of any future changes to the library and will get compile errors if anything is renamed or removed.
From discussion: https://github.com/angularsen/UnitsNet/discussions/1513#discussioncomment-12243230