예제 #1
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual void Update(IUpdateEntry entry)
        {
            var key = CreateKey(entry);

            if (_rows.ContainsKey(key))
            {
                var properties           = entry.EntityType.GetProperties().ToList();
                var comparers            = GetStructuralComparers(properties);
                var valueBuffer          = new object[properties.Count];
                var concurrencyConflicts = new Dictionary <IProperty, object>();

                for (var index = 0; index < valueBuffer.Length; index++)
                {
                    if (IsConcurrencyConflict(entry, properties[index], _rows[key][index], concurrencyConflicts))
                    {
                        continue;
                    }

                    valueBuffer[index] = entry.IsModified(properties[index])
                        ? SnapshotValue(properties[index], comparers[index], entry)
                        : _rows[key][index];
                }

                if (concurrencyConflicts.Count > 0)
                {
                    ThrowUpdateConcurrencyException(entry, concurrencyConflicts);
                }

                _rows[key] = valueBuffer;
            }
            else
            {
                throw new DbUpdateConcurrencyException(InMemoryStrings.UpdateConcurrencyException, new[] { entry });
            }
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual void Update(IUpdateEntry entry)
        {
            var key   = CreateKey(entry);
            var value = _docrows.FindById(new BsonValue(key));

            if (value != null)
            {
                var properties           = entry.EntityType.GetProperties().ToList();
                var comparers            = GetStructuralComparers(properties);
                var valueBuffer          = new object[properties.Count];
                var concurrencyConflicts = new Dictionary <IProperty, object>();
                for (int i = 0; i < properties.Count; i++)
                {
                    if (entry.IsModified(properties[i]))
                    {
                        value.Set(properties[i].Name, new BsonValue(SnapshotValue(properties[i], comparers[i], entry)));
                    }
                }
                _docrows.Update(new BsonValue(key), BsonMapper.Global.ToDocument(value));
            }
            else
            {
                throw new DbUpdateConcurrencyException(LiteDBStrings.UpdateConcurrencyException, new[] { entry });
            }
        }
예제 #3
0
            public void RecordValue(IProperty property, IUpdateEntry entry)
            {
                switch (entry.EntityState)
                {
                case EntityState.Modified:
                    if (!_write &&
                        entry.IsModified(property))
                    {
                        _write        = true;
                        _currentValue = entry.GetCurrentValue(property);
                    }

                    break;

                case EntityState.Added:
                    _currentValue = entry.GetCurrentValue(property);
                    _write        = !property.GetValueComparer().Equals(_originalValue, _currentValue);

                    break;

                case EntityState.Deleted:
                    _originalValue = entry.GetOriginalValue(property);
                    if (!_write &&
                        !property.IsPrimaryKey())
                    {
                        _write        = true;
                        _currentValue = null;
                    }

                    break;
                }
            }
예제 #4
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual void Update(IUpdateEntry entry)
        {
            var key = CreateKey(entry);

            if (_rows.ContainsKey(key))
            {
                var properties           = entry.EntityType.GetProperties().ToList();
                var valueBuffer          = new object[properties.Count];
                var concurrencyConflicts = new Dictionary <IProperty, object>();

                for (var index = 0; index < valueBuffer.Length; index++)
                {
                    if (properties[index].IsConcurrencyToken && !Equals(_rows[key][index], entry.GetOriginalValue(properties[index])))
                    {
                        concurrencyConflicts.Add(properties[index], _rows[key][index]);
                        continue;
                    }
                    valueBuffer[index] = entry.IsModified(properties[index])
                        ? entry.GetCurrentValue(properties[index])
                        : _rows[key][index];
                }

                if (concurrencyConflicts.Any())
                {
                    ThrowUpdateConcurrencyException(entry, concurrencyConflicts);
                }

                _rows[key] = valueBuffer;
            }
            else
            {
                throw new DbUpdateConcurrencyException(InMemoryStrings.UpdateConcurrencyException, new[] { entry });
            }
        }
예제 #5
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="UpdateEntryDto"/> class.
        /// </summary>
        /// <param name="entry">The state entry of an entity.</param>
        /// <param name="mapper">The <see cref="IDynamicObjectMapper" /> used for mapping the property values.</param>
        public UpdateEntryDto(IUpdateEntry entry, IDynamicObjectMapper mapper)
        {
            DynamicObject CreateValueDto(IProperty propertyBase, object value)
            {
                value = Utils.ConvertToProvider(value, propertyBase);
                return(mapper.MapObject(value));
            }

            this.EntityTypeName = entry.EntityType.DisplayName();
            this.EntityState    = entry.EntityState;
            this.PropertyDatas  = entry.ToEntityEntry().Properties.Select(
                prop => new PropertyData
            {
                Name             = prop.Metadata.Name,
                OriginalValueDto = prop.Metadata.GetOriginalValueIndex() >= 0 ? CreateValueDto(prop.Metadata, prop.OriginalValue) : null,
                CurrentValueDto  = CreateValueDto(prop.Metadata, prop.CurrentValue),
                IsModified       = prop.IsModified,
                IsTemporary      = prop.IsTemporary,
            }).ToList();

            if (entry.EntityType.HasDefiningNavigation())
            {
                var ownership = entry.EntityType.GetForeignKeys().Single(fk => fk.IsOwnership);
                this.DelegatedIdentityDatas = ownership.Properties.Select(
                    prop => new PropertyData
                {
                    Name             = prop.Name,
                    OriginalValueDto = CreateValueDto(prop, entry.GetOriginalValue(prop)),
                    CurrentValueDto  = CreateValueDto(prop, entry.GetCurrentValue(prop)),
                    IsModified       = entry.IsModified(prop),
                    IsTemporary      = entry.HasTemporaryValue(prop),
                }).ToList();
            }
        }
예제 #6
0
        public JObject UpdateDocument(JObject document, IUpdateEntry entry)
        {
            foreach (var property in entry.EntityType.GetProperties())
            {
                if (property.Name != StoreKeyConvention.JObjectPropertyName &&
                    property.Name != StoreKeyConvention.IdPropertyName &&
                    (entry.EntityState == EntityState.Added ||
                     entry.IsModified(property)))
                {
                    var value = entry.GetCurrentValue(property);
                    document[property.Name] = value != null?JToken.FromObject(value) : null;
                }
            }

            foreach (var ownedNavigation in entry.EntityType.GetNavigations())
            {
                var fk = ownedNavigation.ForeignKey;
                if (!fk.IsOwnership ||
                    ownedNavigation.IsDependentToPrincipal() ||
                    fk.DeclaringEntityType.IsDocumentRoot())
                {
                    continue;
                }

                var nestedDocumentSource = _database.GetDocumentSource(fk.DeclaringEntityType);
                var nestedValue          = entry.GetCurrentValue(ownedNavigation);
                if (nestedValue == null)
                {
                    document[ownedNavigation.Name] = null;
                }
                else if (fk.IsUnique)
                {
                    var nestedEntry    = ((InternalEntityEntry)entry).StateManager.TryGetEntry(nestedValue, fk.DeclaringEntityType);
                    var nestedDocument = (JObject)document[ownedNavigation.Name];
                    if (nestedDocument != null)
                    {
                        nestedDocumentSource.UpdateDocument(nestedDocument, nestedEntry);
                    }
                    else
                    {
                        nestedDocument = nestedDocumentSource.CreateDocument(nestedEntry);
                    }

                    document[ownedNavigation.Name] = nestedDocument;
                }
                else
                {
                    var array = new JArray();
                    foreach (var dependent in (IEnumerable)nestedValue)
                    {
                        var dependentEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
                        array.Add(_database.GetDocumentSource(dependentEntry.EntityType).CreateDocument(dependentEntry));
                    }

                    document[ownedNavigation.Name] = array;
                }
            }

            return(document);
        }
예제 #7
0
            public bool TryPropagate(IProperty property, IUpdateEntry entry)
            {
                if (_write &&
                    (entry.EntityState == EntityState.Unchanged ||
                     (entry.EntityState == EntityState.Modified && !entry.IsModified(property)) ||
                     (entry.EntityState == EntityState.Added && Equals(_originalValue, entry.GetCurrentValue(property)))))
                {
                    entry.SetStoreGeneratedValue(property, _currentValue);

                    return(false);
                }

                return(_write);
            }
            public bool TryPropagate(IProperty property, IUpdateEntry entry)
            {
                if (_write &&
                    (entry.EntityState == EntityState.Unchanged ||
                     (entry.EntityState == EntityState.Modified && !entry.IsModified(property)) ||
                     (entry.EntityState == EntityState.Added && Equals(_originalValue, entry.GetCurrentValue(property)))))
                {
                    ((InternalEntityEntry)entry)[property] = _currentValue;

                    return(false);
                }

                return(_write);
            }
예제 #9
0
        private JObject UpdateDocument(JObject document, IUpdateEntry entry)
        {
            foreach (var property in _entityType.GetProperties())
            {
                if (property.Name != StoreKeyConvention.JObjectPropertyName &&
                    entry.IsModified(property))
                {
                    var value = entry.GetCurrentValue(property);
                    document[property.Name] = value != null?JToken.FromObject(value) : null;
                }
            }

            return(document);
        }
            public void RecordValue(IProperty property, IUpdateEntry entry)
            {
                switch (entry.EntityState)
                {
                case EntityState.Modified:
                    if (!_write &&
                        entry.IsModified(property))
                    {
                        _write        = true;
                        _currentValue = entry.GetCurrentValue(property);
                    }

                    break;

                case EntityState.Added:
                    _currentValue = entry.GetCurrentValue(property);

                    var comparer = property.GetValueComparer() ?? property.FindTypeMapping()?.Comparer;
                    if (comparer == null)
                    {
                        _write = !Equals(_originalValue, _currentValue);
                    }
                    else
                    {
                        _write = !comparer.Equals(_originalValue, _currentValue);
                    }

                    break;

                case EntityState.Deleted:
                    _originalValue = entry.GetOriginalValue(property);
                    if (!_write &&
                        !property.IsPrimaryKey())
                    {
                        _write        = true;
                        _currentValue = null;
                    }

                    break;
                }
            }
예제 #11
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual void Update(IUpdateEntry entry)
        {
            TKey key = CreateKey(entry);

            if (_rows.ContainsKey(key))
            {
                List <IProperty> properties  = entry.EntityType.GetProperties().ToList();
                object[]         valueBuffer = new object[properties.Count];

                for (int index = 0; index < valueBuffer.Length; index++)
                {
                    valueBuffer[index] = entry.IsModified(properties[index])
                        ? entry.GetCurrentValue(properties[index])
                        : _rows[key][index];
                }

                _rows[key] = valueBuffer;
            }
            else
            {
                throw new DbUpdateConcurrencyException(FileContextStrings.UpdateConcurrencyException, new[] { entry });
            }
        }
예제 #12
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual JObject UpdateDocument([NotNull] JObject document, [NotNull] IUpdateEntry entry, int?ordinal)
        {
            var anyPropertyUpdated = false;

#pragma warning disable EF1001 // Internal EF Core API usage.
            // #16707
            var stateManager = ((InternalEntityEntry)entry).StateManager;
#pragma warning restore EF1001 // Internal EF Core API usage.
            foreach (var property in entry.EntityType.GetProperties())
            {
                if (entry.EntityState == EntityState.Added ||
                    entry.IsModified(property))
                {
                    var storeName = property.GetJsonPropertyName();
                    if (storeName.Length != 0)
                    {
                        document[storeName] = ConvertPropertyValue(property, entry.GetCurrentValue(property));
                        anyPropertyUpdated  = true;
                    }
                }

                if (ordinal != null &&
                    entry.HasTemporaryValue(property) &&
                    property.IsOrdinalKeyProperty())
                {
                    entry.SetStoreGeneratedValue(property, ordinal.Value);
                }
            }

            foreach (var ownedNavigation in entry.EntityType.GetNavigations())
            {
                var fk = ownedNavigation.ForeignKey;
                if (!fk.IsOwnership ||
                    ownedNavigation.IsOnDependent ||
                    fk.DeclaringEntityType.IsDocumentRoot())
                {
                    continue;
                }

                var embeddedDocumentSource = _database.GetDocumentSource(fk.DeclaringEntityType);
                var embeddedValue          = entry.GetCurrentValue(ownedNavigation);
                var embeddedPropertyName   = fk.DeclaringEntityType.GetContainingPropertyName();
                if (embeddedValue == null)
                {
                    if (document[embeddedPropertyName] != null)
                    {
                        document[embeddedPropertyName] = null;
                        anyPropertyUpdated             = true;
                    }
                }
                else if (fk.IsUnique)
                {
#pragma warning disable EF1001 // Internal EF Core API usage.
                    // #16707
                    var embeddedEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(embeddedValue, fk.DeclaringEntityType);
#pragma warning restore EF1001 // Internal EF Core API usage.
                    if (embeddedEntry == null)
                    {
                        continue;
                    }

                    var embeddedDocument = embeddedDocumentSource.GetCurrentDocument(embeddedEntry);
                    embeddedDocument = embeddedDocument != null
                        ? embeddedDocumentSource.UpdateDocument(embeddedDocument, embeddedEntry)
                        : embeddedDocumentSource.CreateDocument(embeddedEntry);

                    if (embeddedDocument != null)
                    {
                        document[embeddedPropertyName] = embeddedDocument;
                        anyPropertyUpdated             = true;
                    }
                }
                else
                {
                    var embeddedOrdinal    = 0;
                    var ordinalKeyProperty = GetOrdinalKeyProperty(fk.DeclaringEntityType);
                    if (ordinalKeyProperty != null)
                    {
                        var shouldSetTemporaryKeys = false;
                        foreach (var dependent in (IEnumerable)embeddedValue)
                        {
#pragma warning disable EF1001 // Internal EF Core API usage.
                            // #16707
                            var embeddedEntry = stateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
                            if (embeddedEntry == null)
                            {
                                continue;
                            }

                            if ((int)embeddedEntry.GetCurrentValue(ordinalKeyProperty) != embeddedOrdinal)
                            {
                                shouldSetTemporaryKeys = true;
                                break;
                            }
#pragma warning restore EF1001 // Internal EF Core API usage.

                            embeddedOrdinal++;
                        }

                        if (shouldSetTemporaryKeys)
                        {
                            var temporaryOrdinal = -1;
                            foreach (var dependent in (IEnumerable)embeddedValue)
                            {
#pragma warning disable EF1001 // Internal EF Core API usage.
                                // #16707
                                var embeddedEntry = stateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
                                if (embeddedEntry == null)
                                {
                                    continue;
                                }

                                embeddedEntry.SetTemporaryValue(ordinalKeyProperty, temporaryOrdinal, setModified: false);
#pragma warning restore EF1001 // Internal EF Core API usage.

                                temporaryOrdinal--;
                            }
                        }
                    }

                    embeddedOrdinal = 0;
                    var array = new JArray();
                    foreach (var dependent in (IEnumerable)embeddedValue)
                    {
#pragma warning disable EF1001 // Internal EF Core API usage.
                        // #16707
                        var embeddedEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
#pragma warning restore EF1001 // Internal EF Core API usage.
                        if (embeddedEntry == null)
                        {
                            continue;
                        }

                        var embeddedDocument = embeddedDocumentSource.GetCurrentDocument(embeddedEntry);
                        embeddedDocument = embeddedDocument != null
                            ? embeddedDocumentSource.UpdateDocument(embeddedDocument, embeddedEntry, embeddedOrdinal) ?? embeddedDocument
                            : embeddedDocumentSource.CreateDocument(embeddedEntry, embeddedOrdinal);

                        array.Add(embeddedDocument);
                        embeddedOrdinal++;
                    }

                    document[embeddedPropertyName] = array;
                    anyPropertyUpdated             = true;
                }
            }

            return(anyPropertyUpdated ? document : null);
        }
예제 #13
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual JObject UpdateDocument(JObject document, IUpdateEntry entry)
        {
            var anyPropertyUpdated = false;

            foreach (var property in entry.EntityType.GetProperties())
            {
                if (entry.EntityState == EntityState.Added ||
                    entry.IsModified(property))
                {
                    var storeName = property.GetCosmosPropertyName();
                    if (storeName.Length != 0)
                    {
                        document[storeName] = ConvertPropertyValue(property, entry.GetCurrentValue(property));
                        anyPropertyUpdated  = true;
                    }
                    else if (entry.HasTemporaryValue(property))
                    {
                        ((InternalEntityEntry)entry)[property] = entry.GetCurrentValue(property);
                    }
                }
            }

            foreach (var ownedNavigation in entry.EntityType.GetNavigations())
            {
                var fk = ownedNavigation.ForeignKey;
                if (!fk.IsOwnership ||
                    ownedNavigation.IsDependentToPrincipal() ||
                    fk.DeclaringEntityType.IsDocumentRoot())
                {
                    continue;
                }

                var embeddedDocumentSource = _database.GetDocumentSource(fk.DeclaringEntityType);
                var embeddedValue          = entry.GetCurrentValue(ownedNavigation);
                var embeddedPropertyName   = fk.DeclaringEntityType.GetCosmosContainingPropertyName();
                if (embeddedValue == null)
                {
                    if (document[embeddedPropertyName] != null)
                    {
                        document[embeddedPropertyName] = null;
                        anyPropertyUpdated             = true;
                    }
                }
                else if (fk.IsUnique)
                {
                    var embeddedEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(embeddedValue, fk.DeclaringEntityType);
                    if (embeddedEntry == null)
                    {
                        continue;
                    }

                    var embeddedDocument = embeddedDocumentSource.GetCurrentDocument(embeddedEntry);
                    embeddedDocument = embeddedDocument != null
                        ? embeddedDocumentSource.UpdateDocument(embeddedDocument, embeddedEntry)
                        : embeddedDocumentSource.CreateDocument(embeddedEntry);

                    if (embeddedDocument != null)
                    {
                        document[embeddedPropertyName] = embeddedDocument;
                        anyPropertyUpdated             = true;
                    }
                }
                else
                {
                    var array = new JArray();
                    foreach (var dependent in (IEnumerable)embeddedValue)
                    {
                        var embeddedEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
                        if (embeddedEntry == null)
                        {
                            continue;
                        }

                        var embeddedDocument = embeddedDocumentSource.GetCurrentDocument(embeddedEntry);
                        embeddedDocument = embeddedDocument != null
                            ? embeddedDocumentSource.UpdateDocument(embeddedDocument, embeddedEntry) ?? embeddedDocument
                            : embeddedDocumentSource.CreateDocument(embeddedEntry);

                        array.Add(embeddedDocument);
                    }

                    document[embeddedPropertyName] = array;
                    anyPropertyUpdated             = true;
                }
            }

            return(anyPropertyUpdated ? document : null);
        }