So what I'm basically doing is parsing a message (HL7 standard).
Sometimes these HL7 messages contain a "whole" record, with all the information, sometimes there is just the updated parts in it.
Here's an example of a row of data. Lets say this row contains some patient/client information like name, date of birth, etc. It could look like this:
|Mike|Miller|19790530|truck driver|blonde|m|
with the columns representing actually this:
|first name|surname|date of birth|job|hair color|gender|
Now this is a whole row of data.
An update might look like this (he married, lost his job and changed his hair color):
||O'Connor||""|brown||
where ""
represents the value of the job column and brown
represents the change of his hair color.
In the HL7 standard it's stated that omitting fields (like first name or gender, for instance) means that no change has been made, where as the ""
means that the data in this field has been deleted. Fields with values might need an update. So my update logic for first name would look similar to this (pidEntity
is a database object, not created code first, but database first and pidEntity.FirstName
is a property)
var pid = this.message.PID; // patient identification object from parsed message
if (pid.PatientName.GivenName.Value == string.Empty)
{
// "" => deletion flag
pidEntity.FirstName = null;
}
else if (pid.PatientName.GivenName.Value == null)
{
// omitted, no changes
return;
}
pidEntity.FirstName = pid.PatientName.GivenName.Value;
I do a lot of string updates like this, so I thought hey - why not try with an extension method or method with ref
parameter.
My first try was this:
// doesn't work because strings are immutable
public static void Update(this string @this, string newValue)
{
if (newValue == string.Empty) @this = null;
else if (newValue == null) return;
@this = newValue;
}
// usage
pidEntity.FirstName.Update(pid.PatientName.GivenName.Value);
Changing the first parameter to this ref string @this
does not work either. Neither does an update function with out
or ref
because properties can't be passed as a ref or out argument like this:
public static void Update(ref string property, string newValue)
// usage
Update(pidEntity.FirstName, pid.PatientName.GivenName.Value);
The most "elegant" I could come up with so far was either this, ignoring the fact that ""
means set the database object's value to null
and set it to an empty string instead.
pidEntity.FirstName = pid.PatientName.GivenName.Value ?? pidEntity.FirstName;
My other solution was an extension method working like this:
public static void UpdateString(this string hl7Value, Action<string> updateAct)
{
if (updateAct == null) throw new ArgumentNullException(nameof(updateAct));
if (hl7Value == string.Empty) updateAct(null);
else if (hl7Value == null) return;
updateAct(hl7Value);
}
// usage
pid.PatientName.GivenName.Value.UpdateString(v => pidEntity.FirstName = v);
I think there must be an easier way, but I need your help (maybe Reflection?) :)