/// <summary> /// Creates a new instance of an object to reflect the changes between the remote and local items. /// This item includes the changes plus the primary key value (unchanged). /// </summary> /// <param name="item1">The <see cref="object"/> representing the remote item</param> /// <param name="item2">The <see cref="object"/> representing the local item</param> /// <returns></returns> private object DBCreateUpdateItem(object item1, object item2, DBSchema schema) { // Get the type of model Type modelType = item1.GetType(); // Create a new instance of the model var updatedItem = Activator.CreateInstance(modelType); // Test the property values foreach (var prop in modelType.GetProperties()) { if (schema.GetPrimaryKey(modelType) == prop) { prop.SetValue(updatedItem, prop.GetValue(item2)); } else { switch (prop.PropertyType.ToString()) { case "System.Guid": case "System.Nullable`1[System.Guid]": if (Guid.Parse(prop.GetValue(item1).ToString()).CompareTo(Guid.Parse(prop.GetValue(item2).ToString())) != 0) { prop.SetValue(updatedItem, prop.GetValue(item2) ?? prop.PropertyType.GetDefault()); } break; case "System.Boolean": case "System.Nullable`1[System.Boolean]": if ((prop.GetValue(item1) as bool?).GetValueOrDefault() != (prop.GetValue(item2) as bool?).GetValueOrDefault()) { prop.SetValue(updatedItem, prop.GetValue(item2) ?? prop.PropertyType.GetDefault()); } break; case "System.DateTimeOffset": case "System.Nullable`1[System.DateTimeOffset]": if (DateTimeOffset.Compare((DateTimeOffset)prop.GetValue(item1), (DateTimeOffset)prop.GetValue(item2)) != 0) { prop.SetValue(updatedItem, prop.GetValue(item2) ?? prop.PropertyType.GetDefault()); } break; default: if (prop.GetValue(item1) != prop.GetValue(item2)) { prop.SetValue(updatedItem, prop.GetValue(item2) ?? prop.PropertyType.GetDefault()); } break; } } } // Return the updated item return(updatedItem); }
/// <summary> /// /// </summary> /// <typeparam name="TModel"></typeparam> /// <param name="action"></param> /// <param name="item"></param> /// <param name="schema"></param> internal async Task RunAction <TModel>(DBAction action, TModel item, DBSchema schema) where TModel : class, new() { // Get primary key property info var pk = schema.GetPrimaryKey(item.GetType()); switch (action) { case DBAction.Push: await Push(item); break; case DBAction.Remove: var rmethod = GetType().GetMethod(nameof(Remove)); var rgenMethod = rmethod.MakeGenericMethod(item.GetType()); Action <TModel> rwhere = i => pk.SetValue(i, pk.GetValue(item)); var t1 = (Task)rgenMethod.Invoke(this, new object[] { rwhere }); await t1; break; case DBAction.Update: var umethod = GetType().GetMethod(nameof(Update)); var ugenMethod = umethod.MakeGenericMethod(item.GetType()); Action <TModel> uwhere = i => { pk.SetValue(i, pk.GetValue(item)); foreach (var prop in i.GetType().GetProperties()) { if (prop.GetValue(item) != null && prop != pk) { prop.SetValue(i, prop.GetValue(item)); } } }; var t2 = (Task)ugenMethod.Invoke(this, new object[] { uwhere }); await t2; break; default: break; } }