While I can see what you are trying to do, there as already a built in mechanism for achieving partial updates without having to build a Linq Expression of the changed values.
I think OrmLite's UpdateNonDefaults
is better suited to your task.
Your Update action should only be receiving changes to your existing record in the DTO, not a full object. So doing this, should be sufficient:
db.UpdateNonDefaults(dto, u => u.Id == 123);
Results in SQL:
UPDATE "User" SET "FirstName" = 'admin', "LastName" = 'my' WHERE ("UserId" = 123);
If your update request where to contain a full object, the database would simply overwrite all the existing values with the same values, but this action shouldn't cost anymore than the processing time to lookup the entire existing object, make comparisons to determine changes using reflection, build a Linq Expression and run an UpdateOnly
query.
If you were dead set on checking for changed fields against the original then you could do it without the complexity of the Linq Expression. Your Merge function could do this (PseudoCode):
public T Merge(T target, T source)
{
- Create a new default object for the return. i.e.
var result = default(T);
Reflect your
T target
public properties:foreach(var property in target.GetType().GetPublicProperties()){
With each reflected property:
Determine whether the value changed using an
EqualityComparer
:if(!EqualityComparer<FieldType>.Default.Equals(targetField, sourceField))
Set the value on the
result
object if the value is different.
Return the
result
object. It will only have the changes.
Now using UpdateNonDefaults
with the result will ensure only the changes are included in the update SQL.
Is it worthwhile to do check of the changed fields? You should perhaps run some benchmarks. Remember that checking involves:
- Querying the database for the entire existing record.
- Reflecting properties on your target and source object.
- Making comparisons of values.
- Building a Linq Expression or new Object to keep track of what's changed.
- Running the update function.
If you get stuck determining the changes on your objects, the answers in this question may help.
I hope this helps.