/// <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 InternalEntityEntry GetOrCreateEntry(object entity)
        {
            var entry = TryGetEntry(entity);

            if (entry == null)
            {
                _trackingQueryMode = TrackingQueryMode.Multiple;

                var entityType = _model.FindRuntimeEntityType(entity.GetType());
                if (entityType == null)
                {
                    if (_model.HasEntityTypeWithDefiningNavigation(entity.GetType()))
                    {
                        throw new InvalidOperationException(
                                  CoreStrings.UntrackedDependentEntity(
                                      entity.GetType().ShortDisplayName(),
                                      "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)));
                    }

                    throw new InvalidOperationException(CoreStrings.EntityTypeNotFound(entity.GetType().ShortDisplayName()));
                }

                if (entityType.IsQueryType)
                {
                    throw new InvalidOperationException(CoreStrings.QueryTypeNotValid(entityType.DisplayName()));
                }

                entry = _internalEntityEntryFactory.Create(this, entityType, entity);

                _entityReferenceMap[entity] = entry;
            }
            return(entry);
        }
Esempio n. 2
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 InternalEntityEntry CreateEntry(IDictionary <string, object> values, IEntityType entityType)
        {
            _trackingQueryMode = TrackingQueryMode.Multiple;

            var i           = 0;
            var valuesArray = new object[entityType.PropertyCount()];

            foreach (var property in entityType.GetProperties())
            {
                valuesArray[i++] = values.TryGetValue(property.Name, out var value)
                    ? value
                    : property.ClrType.GetDefaultValue();
            }

            var valueBuffer = new ValueBuffer(valuesArray);

            var entity = entityType.HasClrType()
                ? EntityMaterializerSource.GetMaterializer(entityType)(
                new MaterializationContext(valueBuffer, Context))
                : null;

            var entry = _internalEntityEntryFactory.Create(this, entityType, entity, valueBuffer);

            UpdateReferenceMaps(entry, EntityState.Detached, null);

            return(entry);
        }
Esempio n. 3
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 InternalEntityEntry GetOrCreateEntry(object entity, IEntityType entityType)
        {
            var entry = TryGetEntry(entity, entityType);

            if (entry == null)
            {
                _trackingQueryMode = TrackingQueryMode.Multiple;

                var runtimeEntityType = _model.FindRuntimeEntityType(entity.GetType());
                if (runtimeEntityType != null)
                {
                    if (!entityType.IsAssignableFrom(runtimeEntityType))
                    {
                        throw new InvalidOperationException(CoreStrings.TrackingTypeMismatch(
                                                                runtimeEntityType.DisplayName(), entityType.DisplayName()));
                    }
                    entityType = runtimeEntityType;
                }

                if (entityType.FindPrimaryKey() == null)
                {
                    throw new InvalidOperationException(CoreStrings.KeylessTypeTracked(entityType.DisplayName()));
                }

                entry = _internalEntityEntryFactory.Create(this, entityType, entity);

                UpdateReferenceMaps(entry, EntityState.Detached, null);
            }

            return(entry);
        }
Esempio n. 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 InternalEntityEntry GetOrCreateEntry(object entity)
        {
            var entry = TryGetEntry(entity);

            if (entry == null)
            {
                _trackingQueryMode = TrackingQueryMode.Multiple;

                var entityType = _model.FindEntityType(entity.GetType());

                if (entityType == null)
                {
                    if (_model.IsDelegatedIdentityEntityType(entity.GetType()))
                    {
                        throw new InvalidOperationException(CoreStrings.UntrackedDelegatedIdentityEntity(
                                                                entity.GetType().ShortDisplayName(),
                                                                "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)));
                    }
                    else
                    {
                        throw new InvalidOperationException(CoreStrings.EntityTypeNotFound(entity.GetType().ShortDisplayName()));
                    }
                }

                entry = _factory.Create(this, entityType, entity);

                _entityReferenceMap[entity] = entry;
            }
            return(entry);
        }
Esempio n. 5
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 InternalEntityEntry GetOrCreateEntry(IDictionary <string, object> values, IEntityType entityType)
        {
            var entry = TryGetEntry(values);

            if (entry == null)
            {
                object entity;
                _trackingQueryMode = TrackingQueryMode.Multiple;

                if (entityType.HasClrType())
                {
                    // Remove when issue #749 is fixed
                    entity = Activator.CreateInstance(entityType.ClrType);
                    entry  = _internalEntityEntryFactory.Create(this, entityType, entity);
                }
                else
                {
                    entry  = new InternalShadowEntityEntry(this, entityType);
                    entity = entry;
                }

                _entityReferenceMap[entity] = entry;
            }

            entry.ToEntityEntry().CurrentValues.SetValues(values);
            return(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 BeginTrackingQuery()
 {
     if (_queryIsTracked)
     {
         _trackingQueryMode = TrackingQueryMode.Multiple;
     }
     else
     {
         _queryIsTracked = true;
     }
 }
        /// <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 InternalEntityEntry GetOrCreateEntry(object entity, IEntityType entityType)
        {
            var entry = TryGetEntry(entity, entityType);

            if (entry == null)
            {
                _trackingQueryMode = TrackingQueryMode.Multiple;

                entry = _internalEntityEntryFactory.Create(this, entityType, entity);

                AddToReferenceMap(entry);
            }
            return(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 TrackingQueryMode GetTrackingQueryMode(IEntityType entityType)
        {
            if (_trackingQueryMode == TrackingQueryMode.Simple &&
                _singleQueryModeEntityType != entityType)
            {
                // Drop out if SQM for change of entity type or self-refs since query may not fix them up.
                if (_singleQueryModeEntityType != null ||
                    entityType.GetNavigations().Any(n => entityType.IsSameHierarchy(n.GetTargetType())))
                {
                    _trackingQueryMode = TrackingQueryMode.Single;
                }

                _singleQueryModeEntityType = entityType;
            }

            return(_trackingQueryMode);
        }
Esempio n. 9
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 Reset()
        {
            Unsubscribe();
            _entityReferenceMap.Clear();

            if (_referencedUntrackedEntities.HasValue)
            {
                _referencedUntrackedEntities.Value.Clear();
            }

            _identityMaps?.Clear();
            _identityMap0?.Clear();
            _identityMap1?.Clear();

            _needsUnsubscribe          = false;
            _queryIsTracked            = false;
            _trackingQueryMode         = TrackingQueryMode.Simple;
            _singleQueryModeEntityType = null;
        }
Esempio n. 10
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 InternalEntityEntry GetOrCreateEntry(object entity)
        {
            var entry = TryGetEntry(entity);

            if (entry == null)
            {
                _trackingQueryMode = TrackingQueryMode.Multiple;

                var entityType = _model.FindRuntimeEntityType(entity.GetType());
                if (entityType == null)
                {
                    if (_model.HasEntityTypeWithDefiningNavigation(entity.GetType()))
                    {
                        throw new InvalidOperationException(
                                  CoreStrings.UntrackedDependentEntity(
                                      entity.GetType().ShortDisplayName(),
                                      "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry),
                                      "." + nameof(EntityEntry.Collection) + "()." + nameof(CollectionEntry.GetTargetEntry) +
                                      "()"));
                    }

                    throw new InvalidOperationException(CoreStrings.EntityTypeNotFound(entity.GetType().ShortDisplayName()));
                }

                if (entityType.FindPrimaryKey() == null)
                {
                    throw new InvalidOperationException(CoreStrings.KeylessTypeTracked(entityType.DisplayName()));
                }

                entry = _internalEntityEntryFactory.Create(this, entityType, entity);

                UpdateReferenceMaps(entry, EntityState.Detached, null);
            }

            return(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 EndSingleQueryMode() => _trackingQueryMode = TrackingQueryMode.Multiple;