/// <summary> /// Get the primary key of a given <see cref="Type"/> /// </summary> /// <param name="model"></param> /// <param name="schema"></param> /// <returns></returns> public static PropertyInfo GetPrimaryKey(this DBSchema schema, Type model) { // Get the DBTable containing the constraints for the dbcontext var table = schema.GetType().GetMethod("Model").MakeGenericMethod(model).Invoke(schema, null); // Return the type of the primary key return((PropertyInfo)table.GetType().GetProperty("PrimaryKey").GetValue(table)); }
/// <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> /// Gets wether the <see cref="PropertyInfo"/> given is the Primary Key in the given Schema /// </summary> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> to check</param> /// <param name="Schema">The Schema to use</param> /// <param name="type">The model for wich we're running the action</param> /// <returns></returns> public static bool IsPrimaryKey(this DBSchema Schema, PropertyInfo propertyInfo, Type model) { var output = Schema.GetType().GetMethod("Model").MakeGenericMethod(model).Invoke(Schema, null); if ((PropertyInfo)output.GetType().GetProperty("PrimaryKey").GetValue(output) == propertyInfo) { return(true); } return(false); }
/// <summary> /// Gets the value of the primary key property on a given object based on a Schema /// </summary> /// <param name="obj">The object to get the property value of the primary key from</param> /// <param name="Schema">The schema to check the primary key against</param> /// <returns><see cref="null"/> if the given object's primary key is the value of <see cref="null"/></returns> public static object GetPrimaryKeyValue(this DBSchema Schema, object obj) { foreach (var prop in obj.GetType().GetProperties()) { if (Schema.IsPrimaryKey(prop, obj.GetType())) { return(prop.GetValue(obj)); } } // Should never be reached return(null); }
/// <summary> /// Gets wether the value of the primary key of the given object is set based on a schema /// </summary> /// <param name="obj">The object to check</param> /// <param name="Schema">The schema to check against</param> /// <returns></returns> public static bool HasPrimaryKeyValue(this DBSchema Schema, object obj) { foreach (var prop in obj.GetType().GetProperties()) { if (Schema.IsPrimaryKey(prop, obj.GetType())) { if (prop.GetValue(obj) != null) { return(true); } } } return(false); }
/// <summary> /// /// </summary> /// <param name="Schema"></param> /// <param name="obj"></param> /// <returns></returns> public static bool RequiredValuesCorrect(this DBSchema Schema, object obj) { bool retval = true; var output = Schema.GetType().GetMethod("Model").MakeGenericMethod(obj.GetType()).Invoke(Schema, null); HashSet <MemberInfo> requiredProps = (HashSet <MemberInfo>)output.GetType().GetProperty("RequiredProperties").GetValue(output); foreach (var prop in obj.GetType().GetProperties()) { if (requiredProps.Contains(prop)) { if ((requiredProps.Where(m => m == prop).First() as PropertyInfo)?.GetValue(obj) == null) { retval = false; } } } return(retval); }
/// <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; } }