Beispiel #1
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 CreateDocument([NotNull] IUpdateEntry entry, int?ordinal)
        {
            var document = new JObject();

            foreach (var property in entry.EntityType.GetProperties())
            {
                var storeName = property.GetJsonPropertyName();
                if (storeName.Length != 0)
                {
                    document[storeName] = ConvertPropertyValue(property, entry.GetCurrentValue(property));
                }
                else if (entry.HasTemporaryValue(property))
                {
                    if (ordinal != null &&
                        property.IsOrdinalKeyProperty())
                    {
                        entry.SetStoreGeneratedValue(property, ordinal.Value);
                    }
                }
            }

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

                var embeddedValue        = entry.GetCurrentValue(embeddedNavigation);
                var embeddedPropertyName = fk.DeclaringEntityType.GetContainingPropertyName();
                if (embeddedValue == null)
                {
                    document[embeddedPropertyName] = null;
                }
                else if (fk.IsUnique)
                {
                    var dependentEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(embeddedValue, fk.DeclaringEntityType);
                    document[embeddedPropertyName] = _database.GetDocumentSource(dependentEntry.EntityType).CreateDocument(dependentEntry);
                }
                else
                {
                    var embeddedOrdinal = 0;
                    var array           = new JArray();
                    foreach (var dependent in (IEnumerable)embeddedValue)
                    {
                        var dependentEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(dependent, fk.DeclaringEntityType);
                        array.Add(_database.GetDocumentSource(dependentEntry.EntityType).CreateDocument(dependentEntry, embeddedOrdinal));
                        embeddedOrdinal++;
                    }

                    document[embeddedPropertyName] = array;
                }
            }

            return(document);
        }
Beispiel #2
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);
            }
Beispiel #3
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);
        }