Пример #1
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();
            }
        }
Пример #2
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);
        }
Пример #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 CreateDocument(IUpdateEntry entry)
        {
            var document = new JObject();

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

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

                var embeddedValue        = entry.GetCurrentValue(embeddedNavigation);
                var embeddedPropertyName = fk.DeclaringEntityType.GetCosmosContainingPropertyName();
                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 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));
                    }

                    document[embeddedPropertyName] = array;
                }
            }

            return(document);
        }
Пример #4
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);
        }
Пример #5
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);
        }