// See IChangeTrackingStrategy documentation public void TakeSnapshot(EntityEntry entry) { if (entry != null) { entry.TakeSnapshot(false); } }
public void Adds_original_value_for_scalar_property_when_some_other_original_values_exist() { var mockMemberMetadata1 = new Mock<StateManagerMemberMetadata>(); mockMemberMetadata1.Setup(m => m.IsComplex).Returns(false); var mockMemberMetadata2 = new Mock<StateManagerMemberMetadata>(); mockMemberMetadata2.Setup(m => m.IsComplex).Returns(false); var mockMetadata = new Mock<StateManagerTypeMetadata>(); mockMetadata.Setup(m => m.Member(1)).Returns(mockMemberMetadata1.Object); mockMetadata.Setup(m => m.Member(2)).Returns(mockMemberMetadata2.Object); var entry = new EntityEntry(); entry.SetOriginalEntityValue(mockMetadata.Object, 2, new object(), 7); var userObject = new object(); var value = new object(); entry.SetOriginalEntityValue(mockMetadata.Object, 1, userObject, value); Assert.Equal(1, entry.FindOriginalValueIndex(mockMemberMetadata1.Object, userObject)); Assert.Same( value, entry.GetOriginalEntityValue(mockMetadata.Object, 1, userObject, ObjectStateValueRecord.OriginalReadonly)); }
/// <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 Generate(InternalEntityEntry entry) { var entityEntry = new EntityEntry(entry); foreach (var property in entry.EntityType.GetProperties()) { var isForeignKey = property.IsForeignKey(); if ((property.RequiresValueGenerator || isForeignKey) && property.ClrType.IsDefaultValue(entry[property])) { if (isForeignKey) { _keyPropagator.PropagateValue(entry, property); } else { var valueGenerator = _valueGeneratorSelector.Select(property, property.IsKey() ? property.DeclaringEntityType : entry.EntityType); Debug.Assert(valueGenerator != null); SetGeneratedValue(entry, property, valueGenerator.Next(entityEntry), valueGenerator.GeneratesTemporaryValues); } } } }
/// <summary> /// Creates an EntityKey for a principal entity based on the foreign key values contained /// in this entity. This implies that this entity is at the dependent end of the relationship. /// </summary> /// <param name="dependentEntry">The EntityEntry for the dependent that contains the FK</param> /// <param name="relatedEnd">Identifies the principal end for which a key is required</param> /// <returns>The key, or null if any value in the key is null</returns> public static EntityKey CreateKeyFromForeignKeyValues(EntityEntry dependentEntry, RelatedEnd relatedEnd) { // Note: there is only ever one constraint per association type ReferentialConstraint constraint = ((AssociationType)relatedEnd.RelationMetadata).ReferentialConstraints.First(); Debug.Assert(constraint.FromRole.Identity == relatedEnd.TargetRoleName, "Unexpected constraint role"); return CreateKeyFromForeignKeyValues(dependentEntry, constraint, relatedEnd.GetTargetEntitySetFromRelationshipSet(), useOriginalValues: false); }
private object[] GetValues(object entity, EntityEntry entry, EntityMode entityMode, bool mightBeDirty, ISessionImplementor session) { object[] loadedState = entry.LoadedState; Status status = entry.Status; IEntityPersister persister = entry.Persister; object[] values; if (status == Status.Deleted) { //grab its state saved at deletion values = entry.DeletedState; } else if (!mightBeDirty && loadedState != null) { values = loadedState; } else { CheckId(entity, persister, entry.Id, entityMode); // grab its current state values = persister.GetPropertyValues(entity, entityMode); CheckNaturalId(persister, entry, values, loadedState, entityMode, session); } return values; }
// See IChangeTrackingStrategy documentation public void TakeSnapshot(EntityEntry entry) { if (entry != null && entry.RequiresComplexChangeTracking) { entry.TakeSnapshot(true); } }
private IEnumerable<DataValidationResult> GetErrors(DbEntityValidationException validationException) { foreach (var dbEntityValidationResult in validationException.EntityValidationErrors) { EntityEntry entry = new EntityEntry(dbEntityValidationResult.Entry); IEnumerable<ValidationError> entryErrors = GetEntryErrors(dbEntityValidationResult.ValidationErrors); yield return new DataValidationResult(entry, entryErrors); } }
/// <summary> /// Performs a pessimistic lock upgrade on a given entity, if needed. /// </summary> /// <param name="entity">The entity for which to upgrade the lock.</param> /// <param name="entry">The entity's EntityEntry instance.</param> /// <param name="requestedLockMode">The lock mode being requested for locking. </param> /// <param name="source">The session which is the source of the event being processed.</param> protected virtual void UpgradeLock(object entity, EntityEntry entry, LockMode requestedLockMode, ISessionImplementor source) { if (requestedLockMode.GreaterThan(entry.LockMode)) { // The user requested a "greater" (i.e. more restrictive) form of // pessimistic lock if (entry.Status != Status.Loaded) { throw new ObjectDeletedException("attempted to lock a deleted instance", entry.Id, entry.EntityName); } IEntityPersister persister = entry.Persister; if (log.IsDebugEnabled) { log.Debug(string.Format("locking {0} in mode: {1}", MessageHelper.InfoString(persister, entry.Id, source.Factory), requestedLockMode)); } ISoftLock slock; CacheKey ck; if (persister.HasCache) { ck = new CacheKey(entry.Id, persister.IdentifierType, persister.RootEntityName, source.EntityMode, source.Factory); slock = persister.Cache.Lock(ck, entry.Version); } else { ck = null; slock = null; } try { if (persister.IsVersioned && requestedLockMode == LockMode.Force) { // todo : should we check the current isolation mode explicitly? object nextVersion = persister.ForceVersionIncrement(entry.Id, entry.Version, source); entry.ForceLocked(entity, nextVersion); } else { persister.Lock(entry.Id, entry.Version, entity, requestedLockMode, source); } entry.LockMode = requestedLockMode; } finally { // the database now holds a lock + the object is flushed from the cache, // so release the soft lock if (persister.HasCache) { persister.Cache.Release(ck, slock); } } } }
// See IChangeTrackingStrategy documentation public void UpdateCurrentValueRecord(object value, EntityEntry entry) { // Has change tracker, but may or may not be a proxy bool isProxy = entry.WrappedEntity.IdentityType != _entity.GetType(); entry.UpdateRecordWithoutSetModified(value, entry.CurrentValues); if (isProxy) { entry.DetectChangesInProperties(true); // detect only complex property changes } }
public void Map(EntityEntry entityEntry, EntityEntry auditEntry) { foreach (var propMap in PropertyMap.Values) { try { var originalValue = entityEntry.Property(propMap.EntityProperty.Name).OriginalValue; auditEntry.Property(propMap.AuditProperty.Name).CurrentValue = originalValue; } catch (Exception) { // Ignoring } } auditEntry.Property("ChangeType").CurrentValue = _changeTypeMap[entityEntry.State]; }
internal ObjectStateEntryDbUpdatableDataRecord(EntityEntry cacheEntry, StateManagerTypeMetadata metadata, object userObject) : base(cacheEntry, metadata, userObject) { EntityUtil.CheckArgumentNull(cacheEntry, "cacheEntry"); EntityUtil.CheckArgumentNull(userObject, "userObject"); EntityUtil.CheckArgumentNull(metadata, "metadata"); Debug.Assert(!cacheEntry.IsKeyEntry, "Cannot create an ObjectStateEntryDbUpdatableDataRecord for a key entry"); switch (cacheEntry.State) { case EntityState.Unchanged: case EntityState.Modified: case EntityState.Added: break; default: Debug.Assert(false, "A CurrentValueRecord cannot be created for an entity object that is in a deleted or detached state."); break; } }
internal ObjectStateEntryDbUpdatableDataRecord(EntityEntry cacheEntry, StateManagerTypeMetadata metadata, object userObject) : base(cacheEntry, metadata, userObject) { //Contract.Requires(cacheEntry != null); //Contract.Requires(userObject != null); //Contract.Requires(metadata != null); Debug.Assert(!cacheEntry.IsKeyEntry, "Cannot create an ObjectStateEntryDbUpdatableDataRecord for a key entry"); switch (cacheEntry.State) { case EntityState.Unchanged: case EntityState.Modified: case EntityState.Added: break; default: Debug.Assert( false, "A CurrentValueRecord cannot be created for an entity object that is in a deleted or detached state."); break; } }
public virtual IEnumerable<EntityEntry> TraverseGraph(object entity) { var entry = new EntityEntry(_context, _stateManager.GetOrCreateEntry(entity)); if (entry.State != EntityState.Detached) { yield break; } yield return entry; if (entry.State != EntityState.Detached) { var internalEntry = ((IAccessor<InternalEntityEntry>)entry).Service; var navigations = internalEntry.EntityType.GetNavigations(); foreach (var navigation in navigations) { var navigationValue = internalEntry[navigation]; if (navigationValue != null) { if (navigation.IsCollection()) { foreach (var relatedEntity in (IEnumerable)navigationValue) { foreach (var relatedEntry in TraverseGraph(relatedEntity)) { yield return relatedEntry; } } } else { foreach (var relatedEntry in TraverseGraph(navigationValue)) { yield return relatedEntry; } } } } } }
// See IChangeTrackingStrategy documentation public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value) { // If the target is the entity, then this is a change to a member on the entity itself rather than // a change to some complex type property defined on the entity. In this case we can use the change tracking // API in the normal way. if (ReferenceEquals(target, entry.Entity)) { // equivalent of EntityObject.ReportPropertyChanging() ((IEntityChangeTracker)entry).EntityMemberChanging(member.CLayerName); member.SetValue(target, value); // equivalent of EntityObject.ReportPropertyChanged() ((IEntityChangeTracker)entry).EntityMemberChanged(member.CLayerName); if (member.IsComplex) { // This is required because the OSE contains a separate cache of user objects for // complex objects such that original values can be looked up correctly. entry.UpdateComplexObjectSnapshot(member, target, ordinal, value); } } else { // Must be a complex type. We would like to do this: // ((IEntityChangeTracker)entry).EntityComplexMemberChanging(topLevelMember.CLayerName, target, member.CLayerName); // ((IEntityChangeTracker)entry).EntityComplexMemberChanged(topLevelMember.CLayerName, target, member.CLayerName); // // However, we have no way of getting the topLevelMember.CLayerName. This is because the value record does not // contain any reference to its parent. (In non-POCO, ComplexObject takes care of this.) // Therefore, in this case we are going to just call a localized DetectChanges to make sure that changes in the // complex types are found. // // Note that this case only happens when the entity is POCO and complex types are set through the CurrentValues // object. This is probably not a very common pattern. member.SetValue(target, value); if (entry.State != EntityState.Added) { // Entry is not Detached - checked in ValidateState() in EntityEntry.SetCurrentEntityValue entry.DetectChangesInProperties(true); } } }
internal ObjectStateEntryOriginalDbUpdatableDataRecord_Internal( EntityEntry cacheEntry, StateManagerTypeMetadata metadata, object userObject) : base(cacheEntry, metadata, userObject) { DebugCheck.NotNull(cacheEntry); DebugCheck.NotNull(userObject); DebugCheck.NotNull(metadata); Debug.Assert(!cacheEntry.IsKeyEntry, "Cannot create an ObjectStateEntryOriginalDbUpdatableDataRecord_Internal for a key entry"); switch (cacheEntry.State) { case EntityState.Unchanged: case EntityState.Modified: case EntityState.Deleted: break; default: Debug.Assert(false, "An OriginalValueRecord cannot be created for an object in an added or detached state."); break; } }
internal ObjectStateEntryDbDataRecord(EntityEntry cacheEntry, StateManagerTypeMetadata metadata, object userObject) { Contract.Requires(cacheEntry != null); Contract.Requires(userObject != null); Contract.Requires(metadata != null); Debug.Assert(!cacheEntry.IsKeyEntry, "Cannot create an ObjectStateEntryDbDataRecord for a key entry"); switch (cacheEntry.State) { case EntityState.Unchanged: case EntityState.Modified: case EntityState.Deleted: _cacheEntry = cacheEntry; _userObject = userObject; _metadata = metadata; break; default: Debug.Assert(false, "A DbDataRecord cannot be created for an entity object that is in an added or detached state."); break; } }
protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities) { if (!(entity is ISoftDelete)) { base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities); return; } ISoftDelete softDeleteEntity = (ISoftDelete)entity; softDeleteEntity.Deleted = true; softDeleteEntity.DeleteDate = DateTime.Now; if (log.IsDebugEnabled) { log.Debug("temporal deleting " + MessageHelper.InfoString(persister, entityEntry.Id, session.Factory)); } CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities); CascadeAfterDelete(session, persister, entity, transientEntities); }
public static IEntityPersister GetEntityPersister(this ISession session, Object entity, out EntityEntry oldEntry) { ISessionImplementor sessionImpl = session.GetSessionImplementation(); IPersistenceContext persistenceContext = sessionImpl.PersistenceContext; oldEntry = persistenceContext.GetEntry(entity); if ((oldEntry == null) && (entity is INHibernateProxy)) { INHibernateProxy proxy = entity as INHibernateProxy; Object obj = sessionImpl.PersistenceContext.Unproxy(proxy); oldEntry = sessionImpl.PersistenceContext.GetEntry(obj); } string className; if (oldEntry != null) { className = oldEntry.EntityName; } else { className = sessionImpl.Factory.GetClassMetadata(entity.GetType()).EntityName; } IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className); return persister; }
protected virtual void CancelDeletionForSoftDelete(EntityEntry entry) { if (!(entry.Entity is ISoftDelete)) { return; } entry.State = EntityState.Unchanged; //TODO: Or Modified? IsDeleted = true makes it modified? entry.Entity.As<ISoftDelete>().IsDeleted = true; }
/// <summary> /// Gets a value to be assigned to a property. /// </summary> /// <para>The change tracking entry of the entity for which the value is being generated.</para> /// <returns> The value to be assigned to a property. </returns> public override TValue Next(EntityEntry entry) => _generatorState.Next <TValue>(GetNewLowValue);
public EntityEntryReference(EntityEntry entry) { Entry = entry; OriginalState = entry.State; }
/// <summary> /// 初始化修改审计信息 /// </summary> private void InitModificationAudited(EntityEntry entry) { ModificationAuditedInitializer.Init(entry.Entity, GetSession()); }
public EntityEntryContractResolver(EntityEntry entityEntry) { _entityEntry = entityEntry; }
/// <summary> /// Determine whether the entity is persistent, detached, or transient /// </summary> /// <param name="entity">The entity to check </param> /// <param name="entityName">The name of the entity </param> /// <param name="entry">The entity's entry in the persistence context </param> /// <param name="source">The originating session. </param> /// <returns> The state. </returns> protected virtual EntityState GetEntityState(object entity, string entityName, EntityEntry entry, ISessionImplementor source) { if (entry != null) { // the object is persistent //the entity is associated with the session, so check its status if (entry.Status != Status.Deleted) { // do nothing for persistent instances if (log.IsDebugEnabled) { log.Debug("persistent instance of: " + GetLoggableName(entityName, entity)); } return EntityState.Persistent; } else { //ie. e.status==DELETED if (log.IsDebugEnabled) { log.Debug("deleted instance of: " + GetLoggableName(entityName, entity)); } return EntityState.Deleted; } } else { //the object is transient or detached //the entity is not associated with the session, so //try interceptor and unsaved-value if (ForeignKeys.IsTransient(entityName, entity, AssumedUnsaved, source)) { if (log.IsDebugEnabled) { log.Debug("transient instance of: " + GetLoggableName(entityName, entity)); } return EntityState.Transient; } else { if (log.IsDebugEnabled) { log.Debug("detached instance of: " + GetLoggableName(entityName, entity)); } return EntityState.Detached; } } }
/// <summary> /// 拦截删除操作 /// </summary> protected virtual void InterceptDeletedOperation(EntityEntry entry) { }
public void Update(T entity) { EntityEntry dbEntityEntry = _context.Entry <T>(entity); dbEntityEntry.State = EntityState.Modified; }
private static async Task SeedProducts(IServiceProvider services) { using (var serviceScope = services.GetRequiredService <IServiceScopeFactory>().CreateScope()) { IConfigurationService settingsService = serviceScope.ServiceProvider.GetService <IConfigurationService>(); ApplicationDbContext dbContext = services.GetRequiredService <ApplicationDbContext>(); var productsCount = await dbContext.Products.CountAsync(); var productsToSeed = 35; productsToSeed -= productsCount; if (productsToSeed <= 0) { return; } UserManager <ApplicationUser> userManager = serviceScope.ServiceProvider.GetService <UserManager <ApplicationUser> >(); RoleManager <ApplicationRole> roleManager = serviceScope.ServiceProvider.GetService <RoleManager <ApplicationRole> >(); var faker = new Faker <Product>() .RuleFor(a => a.PublishAt, f => f.Date .Between(DateTime.Now.AddYears(-3), DateTime.Now.AddYears(1))) .RuleFor(a => a.Name, f => f.Commerce.ProductName()) // f.Lorem.Sentence() .RuleFor(a => a.Description, f => f.Lorem.Sentences(2)) .RuleFor(p => p.Price, f => f.Random.Int(min: 50, max: 1000)) // f.Commerce.Price(min: 50, max: 1000) will return a string .RuleFor(p => p.Stock, f => f.Random.Int(min: 0, max: 2500)) .FinishWith(async(f, aproductInstance) => { ICollection <ProductTag> productTags = new List <ProductTag>(); productTags.Add(new ProductTag { Product = aproductInstance, ProductId = aproductInstance.Id, Tag = await dbContext.Tags.OrderBy(t => Guid.NewGuid()).FirstAsync() } ); aproductInstance.ProductTags = productTags; ICollection <ProductCategory> productCategories = new List <ProductCategory>(); productCategories.Add(new ProductCategory { Product = aproductInstance, ProductId = aproductInstance.Id, Category = await dbContext.Categories.OrderBy(t => Guid.NewGuid()).FirstAsync() } ); aproductInstance.ProductCategories = productCategories; aproductInstance.Slug = aproductInstance.Name.Slugify(); var numberOfImages = f.Random.Int(min: 1, max: 3); ICollection <ProductImage> fileUploads = new List <ProductImage>(numberOfImages); for (var i = 0; i < numberOfImages; i++) { var fileName = f.System.FileName("png"); fileUploads.Add(new ProductImage { OriginalFileName = f.System.FileName("png"), FileName = fileName, FilePath = f.Image.LoremPixelUrl(LoremPixelCategory .Business), // "/images/products/" + fileName, FileSize = f.Random.Long(min: 1500, max: 20000), isFeaturedImage = i == 0 }); } aproductInstance.ProductImages = fileUploads; }); List <Product> products = faker.Generate(productsToSeed); products.ForEach(a => { dbContext.Products.Add(a); // dbContext.Entry(a).State = EntityState.Added; }); EntityEntry <Product> entry = dbContext.Products.Add(products[0]); dbContext.Products.AddRange(products); // dbContext.ChangeTracker.DetectChanges(); // var res = dbContext.SaveChanges(); await dbContext.SaveChangesAsync(); } }
public static void AuditRelationAdded(Audit audit, EntityEntry objectStateEntry) #endif { var entry = audit.Configuration.AuditEntryFactory != null? audit.Configuration.AuditEntryFactory(new AuditEntryFactoryArgs(audit, objectStateEntry, AuditEntryState.RelationshipAdded)) : new AuditEntry(); entry.Build(audit, objectStateEntry); entry.State = AuditEntryState.RelationshipAdded; var values = objectStateEntry.CurrentValues; var leftKeys = (EntityKey)values.GetValue(0); var rightKeys = (EntityKey)values.GetValue(1); if (leftKeys.IsTemporary || rightKeys.IsTemporary) { entry.DelayedKey = objectStateEntry; } else { var leftRelationName = values.GetName(0); var rightRelationName = values.GetName(1); foreach (var keyValue in leftKeys.EntityKeyValues) { var value = keyValue.Value; if (audit.Configuration.UseNullForDBNullValue && value == DBNull.Value) { value = null; } var auditEntryProperty = entry.Parent.Configuration.AuditEntryPropertyFactory != null? entry.Parent.Configuration.AuditEntryPropertyFactory(new AuditEntryPropertyArgs(entry, objectStateEntry, leftRelationName, keyValue.Key, null, value)) : new AuditEntryProperty(); auditEntryProperty.Build(entry, leftRelationName, keyValue.Key, null, value); entry.Properties.Add(auditEntryProperty); } foreach (var keyValue in rightKeys.EntityKeyValues) { var value = keyValue.Value; if (audit.Configuration.UseNullForDBNullValue && value == DBNull.Value) { value = null; } var auditEntryProperty = entry.Parent.Configuration.AuditEntryPropertyFactory != null? entry.Parent.Configuration.AuditEntryPropertyFactory(new AuditEntryPropertyArgs(entry, objectStateEntry, rightRelationName, keyValue.Key, null, value)) : new AuditEntryProperty(); auditEntryProperty.Build(entry, rightRelationName, keyValue.Key, null, value); entry.Properties.Add(auditEntryProperty); } } audit.Entries.Add(entry); }
public virtual void Delete(T entity) { EntityEntry dbEntityEntry = _context.Entry <T>(entity); dbEntityEntry.State = EntityState.Deleted; }
public ChangeLogDetailsAuditor(EntityEntry dbEntry, AuditLog log) { DbEntry = dbEntry; _log = log; }
public static bool HasChangedOwnedEntities(this EntityEntry entry) => entry.References.Any(r => r.TargetEntry != null && r.TargetEntry.Metadata.IsOwned() && (r.TargetEntry.State == EntityState.Added || r.TargetEntry.State == EntityState.Modified));
public static IEnumerable <PropertyEntry> GetProperties(this EntityEntry entityEntry) { return(entityEntry.Metadata.GetProperties().Select(p => entityEntry.Property(p.Name))); }
internal void ChangeRelationshipState(EntityEntry targetEntry, RelatedEnd relatedEnd, EntityState requestedState) { Debug.Assert(requestedState != EntityState.Modified, "Invalid requested state for relationsihp"); Debug.Assert(State != EntityState.Modified, "Invalid initial state for relationsihp"); var initialState = State; switch (initialState) { case EntityState.Added: switch (requestedState) { case EntityState.Added: // no-op break; case EntityState.Unchanged: AcceptChanges(); break; case EntityState.Deleted: AcceptChanges(); // cascade deletion is not performed because TransactionManager.IsLocalPublicAPI == true Delete(); break; case EntityState.Detached: // cascade deletion is not performed because TransactionManager.IsLocalPublicAPI == true Delete(); break; default: Debug.Assert(false, "Invalid requested state"); break; } break; case EntityState.Unchanged: switch (requestedState) { case EntityState.Added: ObjectStateManager.ChangeState(this, EntityState.Unchanged, EntityState.Added); State = EntityState.Added; break; case EntityState.Unchanged: //no-op break; case EntityState.Deleted: // cascade deletion is not performed because TransactionManager.IsLocalPublicAPI == true Delete(); break; case EntityState.Detached: // cascade deletion is not performed because TransactionManager.IsLocalPublicAPI == true Delete(); AcceptChanges(); break; default: Debug.Assert(false, "Invalid requested state"); break; } break; case EntityState.Deleted: switch (requestedState) { case EntityState.Added: relatedEnd.Add( targetEntry.WrappedEntity, applyConstraints: true, addRelationshipAsUnchanged: false, relationshipAlreadyExists: true, allowModifyingOtherEndOfRelationship: false, forceForeignKeyChanges: true); ObjectStateManager.ChangeState(this, EntityState.Deleted, EntityState.Added); State = EntityState.Added; break; case EntityState.Unchanged: relatedEnd.Add( targetEntry.WrappedEntity, applyConstraints: true, addRelationshipAsUnchanged: false, relationshipAlreadyExists: true, allowModifyingOtherEndOfRelationship: false, forceForeignKeyChanges: true); ObjectStateManager.ChangeState(this, EntityState.Deleted, EntityState.Unchanged); State = EntityState.Unchanged; break; case EntityState.Deleted: // no-op break; case EntityState.Detached: AcceptChanges(); break; default: Debug.Assert(false, "Invalid requested state"); break; } break; default: Debug.Assert(false, "Invalid entry state"); break; } }
public virtual Task PreCreate(EntityEntry <TEntity> entity) => Task.CompletedTask;
/// <summary> /// Generates an appropriate EntityEntry instance and adds it /// to the event source's internal caches. /// </summary> public EntityEntry AddEntry(object entity, Status status, object[] loadedState, object rowId, object id, object version, LockMode lockMode, bool existsInDatabase, IEntityPersister persister, bool disableVersionIncrement, bool lazyPropertiesAreUnfetched) { EntityEntry e = new EntityEntry(status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister, session.EntityMode, disableVersionIncrement, lazyPropertiesAreUnfetched); entityEntries[entity] = e; SetHasNonReadOnlyEnties(status); return e; }
private object InitializeLazyPropertiesFromDatastore(string fieldName, object entity, ISessionImplementor session, object id, EntityEntry entry) { if (!HasLazyProperties) throw new AssertionFailure("no lazy properties"); log.Debug("initializing lazy properties from datastore"); using (new SessionIdLoggingContext(session.SessionId)) try { object result = null; IDbCommand ps = null; IDataReader rs = null; try { SqlString lazySelect = SQLLazySelectString; if (lazySelect != null) { // null sql means that the only lazy properties // are shared PK one-to-one associations which are // handled differently in the Type#nullSafeGet code... ps = session.Batcher.PrepareCommand(CommandType.Text, lazySelect, IdentifierType.SqlTypes(Factory)); IdentifierType.NullSafeSet(ps, id, 0, session); rs = session.Batcher.ExecuteReader(ps); rs.Read(); } object[] snapshot = entry.LoadedState; for (int j = 0; j < lazyPropertyNames.Length; j++) { object propValue = lazyPropertyTypes[j].NullSafeGet(rs, lazyPropertyColumnAliases[j], session, entity); if (InitializeLazyProperty(fieldName, entity, session, snapshot, j, propValue)) { result = propValue; } } } finally { session.Batcher.CloseCommand(ps, rs); } log.Debug("done initializing lazy properties"); return result; } catch (DbException sqle) { var exceptionContext = new AdoExceptionContextInfo { SqlException = sqle, Message = "could not initialize lazy properties: " + MessageHelper.InfoString(this, id, Factory), Sql = SQLLazySelectString.ToString(), EntityName = EntityName, EntityId = id }; throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, exceptionContext); } }
public virtual void OnMerge(MergeEvent @event, IDictionary copiedAlready) { EventCache copyCache = (EventCache)copiedAlready; IEventSource source = @event.Session; object original = @event.Original; if (original != null) { object entity; if (original.IsProxy()) { ILazyInitializer li = ((INHibernateProxy)original).HibernateLazyInitializer; if (li.IsUninitialized) { log.Debug("ignoring uninitialized proxy"); @event.Result = source.Load(li.EntityName, li.Identifier); return; //EARLY EXIT! } else { entity = li.GetImplementation(); } } else { entity = original; } if (copyCache.Contains(entity) && copyCache.IsOperatedOn(entity)) { log.Debug("already in merge process"); @event.Result = entity; } else { if (copyCache.Contains(entity)) { log.Info("already in copyCache; setting in merge process"); copyCache.SetOperatedOn(entity, true); } @event.Entity = entity; EntityState entityState = EntityState.Undefined; if (ReferenceEquals(null, @event.EntityName)) { @event.EntityName = source.BestGuessEntityName(entity); } // Check the persistence context for an entry relating to this // entity to be merged... EntityEntry entry = source.PersistenceContext.GetEntry(entity); if (entry == null) { IEntityPersister persister = source.GetEntityPersister(@event.EntityName, entity); object id = persister.GetIdentifier(entity); if (id != null) { EntityKey key = source.GenerateEntityKey(id, persister); object managedEntity = source.PersistenceContext.GetEntity(key); entry = source.PersistenceContext.GetEntry(managedEntity); if (entry != null) { // we have specialized case of a detached entity from the // perspective of the merge operation. Specifically, we // have an incoming entity instance which has a corresponding // entry in the current persistence context, but registered // under a different entity instance entityState = EntityState.Detached; } } } if (entityState == EntityState.Undefined) { entityState = GetEntityState(entity, @event.EntityName, entry, source); } switch (entityState) { case EntityState.Persistent: EntityIsPersistent(@event, copyCache); break; case EntityState.Transient: EntityIsTransient(@event, copyCache); break; case EntityState.Detached: EntityIsDetached(@event, copyCache); break; default: throw new ObjectDeletedException("deleted instance passed to merge", null, GetLoggableName(@event.EntityName, entity)); } } } }
public virtual bool IsModifiableEntity(EntityEntry entry) { return (entry == null ? IsMutable : entry.IsModifiableEntity()); }
/// <summary> /// 拦截修改操作 /// </summary> protected virtual void InterceptModifiedOperation(EntityEntry entry) { InitModificationAudited(entry); }
public void Edit(T entity) { EntityEntry dbEntityEntry = context.Entry <T>(entity); dbEntityEntry.State = EntityState.Modified; }
/// <summary> /// 初始化创建审计信息 /// </summary> private void InitCreationAudited(EntityEntry entry) { CreationAuditedInitializer.Init(entry.Entity, GetSession()); }
protected virtual void PreSaveChanges(EntityEntry item) { }
public AdditionLogDetailsAuditor(EntityEntry dbEntry, AuditLog log) : base(dbEntry, log) { }
protected virtual bool IsCreated(EntityEntry entityEntry) { return(entityEntry.State == EntityState.Added); }
protected virtual void ResolveConcurrencyTokens(EntityEntry entry) { // default do nothing. Allow provider-specific entry reset }
public override int Next(EntityEntry entry) { throw new NotImplementedException(); }
protected virtual void SetModificationAuditProperties(EntityEntry entry, long? userId) { if (entry.Entity is IHasModificationTime) { entry.Entity.As<IHasModificationTime>().LastModificationTime = Clock.Now; } if (entry.Entity is IModificationAudited) { var entity = entry.Entity.As<IModificationAudited>(); if (userId == null) { entity.LastModifierUserId = null; return; } //Special check for multi-tenant entities if (entity is IMayHaveTenant || entity is IMustHaveTenant) { //Sets LastModifierUserId only if current user is in same tenant/host with the given entity if ((entity is IMayHaveTenant && entity.As<IMayHaveTenant>().TenantId == AbpSession.TenantId) || (entity is IMustHaveTenant && entity.As<IMustHaveTenant>().TenantId == AbpSession.TenantId)) { entity.LastModifierUserId = userId; } else { entity.LastModifierUserId = null; } } else { entity.LastModifierUserId = userId; } } }
public virtual void OnDelete(DeleteEvent @event, ISet <object> transientEntities) { IEventSource source = @event.Session; IPersistenceContext persistenceContext = source.PersistenceContext; object entity = persistenceContext.UnproxyAndReassociate(@event.Entity); EntityEntry entityEntry = persistenceContext.GetEntry(entity); IEntityPersister persister; object id; object version; if (entityEntry == null) { log.Debug("entity was not persistent in delete processing"); persister = source.GetEntityPersister(@event.EntityName, entity); if (ForeignKeys.IsTransientSlow(persister.EntityName, entity, source)) { DeleteTransientEntity(source, entity, @event.CascadeDeleteEnabled, persister, transientEntities); // EARLY EXIT!!! return; } else { PerformDetachedEntityDeletionCheck(@event); } id = persister.GetIdentifier(entity); if (id == null) { throw new TransientObjectException("the detached instance passed to delete() had a null identifier"); } EntityKey key = source.GenerateEntityKey(id, persister); persistenceContext.CheckUniqueness(key, entity); new OnUpdateVisitor(source, id, entity).Process(entity, persister); version = persister.GetVersion(entity); entityEntry = persistenceContext.AddEntity( entity, persister.IsMutable ? Status.Loaded : Status.ReadOnly, persister.GetPropertyValues(entity), key, version, LockMode.None, true, persister, false, false); } else { log.Debug("deleting a persistent instance"); if (entityEntry.Status == Status.Deleted || entityEntry.Status == Status.Gone) { log.Debug("object was already deleted"); return; } persister = entityEntry.Persister; id = entityEntry.Id; version = entityEntry.Version; } if (InvokeDeleteLifecycle(source, entity, persister)) { return; } DeleteEntity(source, entity, entityEntry, @event.CascadeDeleteEnabled, persister, transientEntities); if (source.Factory.Settings.IsIdentifierRollbackEnabled) { persister.ResetIdentifier(entity, id, version); } }
private static bool UseMinimalPuts(ISessionImplementor session, EntityEntry entityEntry) { return (session.Factory.Settings.IsMinimalPutsEnabled && session.CacheMode != CacheMode.Refresh) || (entityEntry.Persister.HasLazyProperties && entityEntry.LoadedWithLazyPropertiesUnfetched && entityEntry.Persister.IsLazyPropertiesCacheable); }
protected virtual void CascadeBeforeDelete(IEventSource session, IEntityPersister persister, object entity, EntityEntry entityEntry, ISet <object> transientEntities) { ISessionImplementor si = session; CacheMode cacheMode = si.CacheMode; si.CacheMode = CacheMode.Get; session.PersistenceContext.IncrementCascadeLevel(); try { // cascade-delete to collections BEFORE the collection owner is deleted new Cascade(CascadingAction.Delete, CascadePoint.AfterInsertBeforeDelete, session).CascadeOn(persister, entity, transientEntities); } finally { session.PersistenceContext.DecrementCascadeLevel(); si.CacheMode = cacheMode; } }
/// <summary> Set the status of an entry</summary> public void SetEntryStatus(EntityEntry entry, Status status) { entry.Status = status; SetHasNonReadOnlyEnties(status); }
protected override object NextValue(EntityEntry entry) { return(true); }
internal ObjectStateEntryOriginalDbUpdatableDataRecord_Public( EntityEntry cacheEntry, StateManagerTypeMetadata metadata, object userObject, int parentEntityPropertyIndex) : base(cacheEntry, metadata, userObject) { _parentEntityPropertyIndex = parentEntityPropertyIndex; }
/// <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 override short Next(EntityEntry entry) => (short)Interlocked.Increment(ref _current);
public void Delete(TEntity entity) { EntityEntry dbEntityEntry = _context.Entry(entity); dbEntityEntry.State = EntityState.Deleted; }
private object MergeTransientEntity(object entity, string entityName, object requestedId, IEventSource source, IDictionary copyCache) { IEntityPersister persister = source.GetEntityPersister(entityName, entity); object id = persister.HasIdentifierProperty ? persister.GetIdentifier(entity) : null; object copy = null; if (copyCache.Contains(entity)) { copy = copyCache[entity]; persister.SetIdentifier(copy, id); } else { copy = source.Instantiate(persister, id); ((EventCache)copyCache).Add(entity, copy, true); // before cascade! } // cascade first, so that all unsaved objects get their // copy created before we actually copy //cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE); base.CascadeBeforeSave(source, persister, entity, copyCache); CopyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.ForeignKeyFromParent); try { // try saving; check for non-nullable properties that are null or transient entities before saving this.SaveTransientEntity(copy, entityName, requestedId, source, copyCache); } catch (PropertyValueException ex) { string propertyName = ex.PropertyName; object propertyFromCopy = persister.GetPropertyValue(copy, propertyName); object propertyFromEntity = persister.GetPropertyValue(entity, propertyName); IType propertyType = persister.GetPropertyType(propertyName); EntityEntry copyEntry = source.PersistenceContext.GetEntry(copy); if (propertyFromCopy == null || !propertyType.IsEntityType) { log.Info("property '{0}.{1}' is null or not an entity; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromCopy); throw; } if (!copyCache.Contains(propertyFromEntity)) { log.Info("property '{0}.{1}' from original entity is not in copyCache; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); throw; } if (((EventCache)copyCache).IsOperatedOn(propertyFromEntity)) { log.Info("property '{0}.{1}' from original entity is in copyCache and is in the process of being merged; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); } else { log.Info("property '{0}.{1}' from original entity is in copyCache and is not in the process of being merged; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); } // continue...; we'll find out if it ends up not getting saved later } // cascade first, so that all unsaved objects get their // copy created before we actually copy base.CascadeAfterSave(source, persister, entity, copyCache); CopyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.ForeignKeyToParent); return(copy); }
private object InitializeLazyPropertiesFromCache(string fieldName, object entity, ISessionImplementor session, EntityEntry entry, CacheEntry cacheEntry) { log.Debug("initializing lazy properties from second-level cache"); object result = null; object[] disassembledValues = cacheEntry.DisassembledState; object[] snapshot = entry.LoadedState; for (int j = 0; j < lazyPropertyNames.Length; j++) { object propValue = lazyPropertyTypes[j].Assemble(disassembledValues[lazyPropertyNumbers[j]], session, entity); if (InitializeLazyProperty(fieldName, entity, session, snapshot, j, propValue)) { result = propValue; } } log.Debug("done initializing lazy properties"); return result; }
/// <summary> /// 拦截修改操作 /// </summary> protected override void InterceptModifiedOperation(EntityEntry entry) { base.InterceptModifiedOperation(entry); Helper.InitVersion(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> protected override object NextValue(EntityEntry entry) => _discriminator;
public void Add(T entity) { EntityEntry dbEntityEntry = context.Entry <T>(entity); context.Set <T>().Add(entity); }