예제 #1
0
        private object FindTrackedEntity(object entity)
        {
            var eType = ObjectContext.GetObjectType(entity.GetType());

            return(_context.Set(eType)
                   .Local
                   .OfType <object>()
                   .FirstOrDefault(local => _entityManager.AreKeysIdentical(local, entity)));
        }
예제 #2
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 (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);
        }
        private object FindTrackedEntity(object entity)
        {
            var clrType = entity.GetType();

            //var obj = _context.Entry(entity).CurrentValues.ToObject();


            var method = typeof(DbContext).GetMethods().First(m => m.Name == "Set" && m.GetParameters().Length == 0 && m.IsGenericMethod);

            var contextSet = method.MakeGenericMethod(clrType).Invoke(_context, null);
            var localValue = contextSet.GetType().GetProperty("Local").GetValue(contextSet);

            var obj = ((IEnumerable <object>)localValue).FirstOrDefault(local => _entityManager.AreKeysIdentical(local, entity));

            //var obj2 = _context.Set<T>()
            //    .Local
            //    .OfType<object>()
            //    .FirstOrDefault(local => _entityManager.AreKeysIdentical(local, entity));

            return(obj);
        }
예제 #4
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);
            }
        }
예제 #5
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);
            }
        }