/// <summary> /// <para> /// If any <see cref="DBSet{T}"/> belonging to this <see cref="DBContext"/> has any significant changes within the data. /// This function will commit those changes to the database. /// </para> /// </summary> /// <returns></returns> public async Task Commit() { await Task.Run(async() => { // Check if any changes have happened if (!ChangeTracker.Instance.DetectChanges(this)) { return; } // Get all the changes while (ChangeTracker.Instance.Changes.Count > 0) { // Get the DBChange var change = ChangeTracker.Instance.Changes.Dequeue(); // Run the action provided by the DBChange from the changetracker await DBActionProvider.RunAction(change.Action, change.Value, Schema); } }); }
/// <summary> /// Gets the database data /// </summary> /// <returns></returns> private async Task GetDatabaseData() { await Task.Run(() => { // Iterate over every property in the DBContext foreach (var prop in GetType().GetProperties()) { // Check to see if the property type has any generic arguments // The dbsets always need a generic argument and that's what we're trying to get if (prop.PropertyType.GetGenericArguments().Length < 1) { continue; } // Get the generic type (always should be just 1) Type genericType = prop.PropertyType.GetGenericArguments().FirstOrDefault(); // Check to see if the property was of type DBSet<genericType> if (!(prop.PropertyType == typeof(DBSet <>).MakeGenericType(genericType))) { continue; } MethodInfo genMethod; try { // Get the fetch method var method = DBActionProvider.GetType().GetMethod(nameof(DBActionProvider.Fetch)); // Generate the fetch method with the generic type we got earlier genMethod = method.MakeGenericMethod(genericType); } catch (Exception ex) { throw new DBAccessException("Could not instantiate the Fetch method", ex); } // create a task to execute the method object t = null; try { // Execute the generic fetch method for the specified type var p = typeof(Task <>).MakeGenericType(typeof(DBSet <>).MakeGenericType(prop.PropertyType.GetGenericArguments().First())); t = Convert.ChangeType(genMethod.Invoke(DBActionProvider, new object[] { null }), p); } catch (Exception ex) { throw new DBAccessException("Could not generate the task to execute the Fetch method", ex); } // The value object value; try { // Get the database values value = t.GetType().GetProperty("Result")?.GetValue(t); } catch (Exception ex) { throw new DBAccessException("The result from the Fetch method could not be retrieved", ex); } try { // Set the remote values to the ordinary list of the dbset prop.SetValue(this, value); } catch (Exception ex) { throw new DBAccessException($"Could not set the {prop.Name} to the result from the Fetch function", ex); } } }); }