Ejemplo n.º 1
0
        /// <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);
                }
            });
        }
Ejemplo n.º 2
0
        /// <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);
                    }
                }
            });
        }