Exemplo n.º 1
0
        private object AddElement <T>(IChangeTracker changeTracker, IEntityManager entityManager, T existing, object updateItem, object dbCollection)
        {
            if (!_isOwned)
            {
                updateItem = changeTracker.AttachAndReloadAssociatedEntity(updateItem);
            }
            else if (changeTracker.GetItemState(updateItem) == EntityState.Detached)
            {
                var instance = entityManager.CreateEmptyEntityWithKey(updateItem);

                changeTracker.AddItem(instance);
                changeTracker.UpdateItem(updateItem, instance);

                foreach (var childMember in Members)
                {
                    childMember.Update(changeTracker, entityManager, instance, updateItem);
                }

                updateItem = instance;
            }

            dbCollection.GetType().GetMethod("Add").Invoke(dbCollection, new[] { updateItem });

            if (_isOwned)
            {
                changeTracker.AttachCyclicNavigationProperty(existing, updateItem, GetMappedNaviationProperties());
            }

            return(updateItem);
        }
Exemplo n.º 2
0
        private object CreateNewPersistedEntity <T>(IChangeTracker changeTracker, T existing, object newValue) where T : class
        {
            var instance = Activator.CreateInstance(newValue.GetType(), true);

            SetValue(existing, instance);
            changeTracker.AddItem(instance);
            changeTracker.UpdateItem(newValue, instance);
            return(instance);
        }
Exemplo n.º 3
0
        // overridden by different implementations
        public virtual void Update <T>(IChangeTracker changeTracker, IEntityManager entityManager, T persisted, T updating) where T : class
        {
            changeTracker.UpdateItem(updating, persisted, true);

            // Foreach branch perform recursive update
            foreach (var member in Members)
            {
                member.Update(changeTracker, entityManager, persisted, updating);
            }
        }
Exemplo n.º 4
0
        private void UpdateElement <T>(IChangeTracker changeTracker, IEntityManager entityManager, T existing, object updateItem, object dbItem)
        {
            if (!_isOwned)
            {
                return;
            }

            changeTracker.UpdateItem(updateItem, dbItem);
            changeTracker.AttachCyclicNavigationProperty(existing, updateItem, GetMappedNaviationProperties());

            foreach (var childMember in Members)
            {
                childMember.Update(changeTracker, entityManager, dbItem, updateItem);
            }
        }
Exemplo n.º 5
0
        public override void Update <T>(IChangeTracker changeTracker, IEntityManager entityManager, T persisted, T updating)
        {
            var dbValue  = GetValue <object>(persisted);
            var newValue = GetValue <object>(updating);

            if (dbValue == null && newValue == null)
            {
                return;
            }

            // Merging options
            // 1. No new value, set value to null. entity will be removed if cascade rules set.
            // 2. If new value is same as old value lets update the members
            // 3. Otherwise new value is set and we don't care about old dbValue, so create a new one.
            if (newValue == null)
            {
                SetValue(persisted, null);
                return;
            }

            if (dbValue != null && entityManager.AreKeysIdentical(newValue, dbValue))
            {
                changeTracker.UpdateItem(newValue, dbValue, true);
            }
            else
            {
                dbValue = CreateNewPersistedEntity(changeTracker, persisted, newValue);
            }

            changeTracker.AttachCyclicNavigationProperty(persisted, newValue, GetMappedNaviationProperties());

            foreach (var childMember in Members)
            {
                childMember.Update(changeTracker, entityManager, dbValue, newValue);
            }
        }
Exemplo n.º 6
0
        public void Update <T>(IChangeTracker changeTracker, IEntityManager entityManager, T persisted, T updating) where T : class
        {
            if (Accessor == null)
            {
                changeTracker.UpdateItem(updating, persisted);

                // Foreach branch perform recursive update
                foreach (var member in Members)
                {
                    member.Update(changeTracker, entityManager, persisted, updating);
                }
            }
            else if (_isCollection)
            {
                //CollectionGraph (Association/Owned)
                var innerElementType = GetCollectionElementType();
                var updateValues     = GetValue <IEnumerable>(updating) ?? new List <object>();
                var dbCollection     = GetValue <IEnumerable>(persisted) ?? CreateMissingCollection(persisted, innerElementType);

                var dbHash = dbCollection.Cast <object>().ToDictionary(item => entityManager.GetEntityKey(item));

                // Iterate through the elements from the updated graph and try to match them against the db graph
                var updateList = updateValues.OfType <object>().ToList();
                for (var i = 0; i < updateList.Count; i++)
                {
                    var updateItem = updateList[i];
                    var key        = entityManager.GetEntityKey(updateItem);

                    // try to find item with same key in db collection
                    object dbItem;
                    if (dbHash.TryGetValue(key, out dbItem))
                    {
                        UpdateElement(changeTracker, entityManager, persisted, updateItem, dbItem);
                        dbHash.Remove(key);
                    }
                    else
                    {
                        updateList[i] = AddElement(changeTracker, entityManager, persisted, updateItem, dbCollection);
                    }
                }

                // remove obsolete items
                foreach (var dbItem in dbHash.Values)
                {
                    RemoveElement(changeTracker, dbItem, dbCollection);
                }
            }
            else if (_isOwned)
            {
                //OwnedEntity

                var dbValue  = GetValue <object>(persisted);
                var newValue = GetValue <object>(updating);

                if (dbValue == null && newValue == null)
                {
                    return;
                }

                // Merging options
                // 1. No new value, set value to null. entity will be removed if cascade rules set.
                // 2. If new value is same as old value lets update the members
                // 3. Otherwise new value is set and we don't care about old dbValue, so create a new one.
                if (newValue == null)
                {
                    SetValue(persisted, null);
                    return;
                }

                if (dbValue != null && entityManager.AreKeysIdentical(newValue, dbValue))
                {
                    changeTracker.UpdateItem(newValue, dbValue);
                }
                else
                {
                    dbValue = CreateNewPersistedEntity(changeTracker, persisted, newValue);
                }

                changeTracker.AttachCyclicNavigationProperty(persisted, newValue, GetMappedNaviationProperties());

                foreach (var childMember in Members)
                {
                    childMember.Update(changeTracker, entityManager, dbValue, newValue);
                }
            }
            else
            {
                //AssociatedEntity
                var dbValue  = GetValue <object>(persisted);
                var newValue = GetValue <object>(updating);

                if (newValue == null)
                {
                    SetValue(persisted, null);
                    return;
                }

                // do nothing if the key is already identical
                if (entityManager.AreKeysIdentical(newValue, dbValue))
                {
                    return;
                }

                newValue = changeTracker.AttachAndReloadAssociatedEntity(newValue);
                SetValue(persisted, newValue);
            }
        }