/// <summary>
 /// Instantiates the class using default components
 /// </summary>
 /// <param name="dbContext">Context in which to perform the merge operation</param>
 /// <param name="modelsNamespace">Namespace in which all context entities are defined (all models must be within
 /// the same namespace. If model type is in a different namespace, an exception will be thrown when instantiating
 /// the type. This is, hopefully, a temporary workaround, until I find a good solution for this)</param>
 /// <param name="modelAssemblyName">Name of assembly which contains all context enties. Again, just like with the
 /// namespace parameter, this is a temporary workaround</param>
 public DefaultEntityChangesMerger(DbContext dbContext, string modelsNamespace, string modelAssemblyName)
 {
     DbContext        = dbContext;
     reflector        = new DbContextReflector(DbContext, modelsNamespace, modelAssemblyName);
     scalarUpdater    = new ScalarPropertyUpdater(DbContext, reflector);
     entityComparer   = new EntityComparerByNonForeignKeys();
     collectionMerger = new CollectionMerger(entityComparer);
     navUpdater       = new NavigationPropertyUpdater(DbContext, scalarUpdater, reflector);
 }
Пример #2
0
        public TEntity UpdateEntity <TEntity>(TEntity model, IRecursiveEntityUpdater updater)
            where TEntity : class
        {
            // Update scalar properties
            TEntity updatedModel = UpdateEntity <TEntity>(model);

            UpdateAllNavigationProperties(updatedModel, model, updater, updatedModel == model);

            return(updatedModel);
        }
Пример #3
0
        /*public void UpdateCollection(Expression<Func<TModel, IList<TCollectionEntry>>> property, object sourceModel)
         * {
         *  MemberExpression mex = (MemberExpression)property.Body;
         *  UpdateCollection((PropertyInfo)mex.Member, sourceModel);
         * }*/

        public void UpdateCollection <TCollectionEntry>(IDbContextReflector reflector, NavigationPropertyInfo property,
                                                        object sourceModel, bool modelIsNew, IRecursiveEntityUpdater entityUpdater)
            where TCollectionEntry : class
        {
            Reflector     = reflector;
            Property      = property;
            EntityUpdater = entityUpdater;

            if (modelIsNew)
            {
                AddCollection((IList <TCollectionEntry>)property.PropertyInfo.GetValue(sourceModel));
            }
            else
            {
                UpdateCollection((IList <TCollectionEntry>)property.PropertyInfo.GetValue(Model),
                                 (IList <TCollectionEntry>)property.PropertyInfo.GetValue(sourceModel));
            }
        }
        protected override void UpdateAllNavigationProperties <TEntity>(TEntity updatedModel, TEntity model, IRecursiveEntityUpdater entityUpdater, bool isNew)
        {
            EntityNavigationPropertyInfo[] collectionProperties = Reflector.GetCollectionNavigationProperties(typeof(TEntity)); // make it work like <TModel>

            var collectionUpdater = new ReflectingGenericCollectionPropertyUpdater <TEntity>(new CollectionPropertyUpdater <TEntity>(DbContext, updatedModel, CollectionMerger));

            foreach (var property in collectionProperties)
            {
                collectionUpdater.UpdateCollectionProperty(Reflector, property, model, isNew, entityUpdater);
            }
        }
Пример #5
0
 protected abstract void UpdateAllNavigationProperties <TEntity>(TEntity updatedModel, TEntity model, IRecursiveEntityUpdater entityUpdater, bool isNew)
     where TEntity : class;
Пример #6
0
        protected override void UpdateAllNavigationProperties <TEntity>(TEntity updatedModel, TEntity model, IRecursiveEntityUpdater entityUpdater, bool modelIsNew)
        {
            EntityNavigationPropertyInfo[] navigationProperties = Reflector.GetDependentNavigationProperties(typeof(TEntity));

            var modelUpdater = new ReflectingGenericEntityUpdater <TEntity>();

            foreach (var property in navigationProperties)
            {
                modelUpdater.UpdateProperty(property, model, entityUpdater);

                /* TODO: cover scenarios where navigation property has a corresponding foreign key (Id) property.
                 * Make sure updates work well in those cases because sometimes navigation property might not be loaded (== null)
                 * but the foreign key property is non-default. In such cases, navigation property of the target model should
                 * not be set to null. */
            }
        }
Пример #7
0
 public void UpdateProperty(EntityNavigationPropertyInfo property, TModel newModel, IRecursiveEntityUpdater entityUpdater)
 {
     GenericMethodInvoker.InvokeGenericMethod(typeof(IRecursiveEntityUpdater), nameof(IRecursiveEntityUpdater.UpdateEntity),
                                              new Type[] { property.PropertyInfo.PropertyType },
                                              GenericMethodInvoker.DefaultPublicInstanceBindingFlags,
                                              new object[] { property.PropertyInfo.GetValue(newModel), entityUpdater },
                                              entityUpdater);
 }