/// <summary> /// Initializes a new instance of the <see cref="UnitOfWorkScope"/> class. /// </summary> public UnitOfWorkScope() { if ( currentScope == null ) { DbContext = new RockContext(); isDisposed = false; currentScope = this; } }
/// <summary> /// Initializes a new instance of the <see cref="UnitOfWorkScope"/> class using a custom dbContext /// </summary> public UnitOfWorkScope(DbContext context) { if ( currentScope == null ) { DbContext = context; isDisposed = false; currentScope = this; } }
/// <summary> /// Initializes a new instance of the <see cref="UnitOfWorkScope"/> class. /// </summary> /// <param name="saveAllChangesAtScopeEnd">if set to <c>true</c> changes should be saved at scope end.</param> public UnitOfWorkScope( bool saveAllChangesAtScopeEnd ) { if ( currentScope != null && !currentScope.isDisposed ) throw new InvalidOperationException( "ObjectContextScope instances can not be nested" ); SaveAllChangesAtScopeEnd = saveAllChangesAtScopeEnd; objectContext = new RockContext(); isDisposed = false; //Thread.BeginThreadAffinity(); --Not supported with Medium Trust currentScope = this; }
public override void PreSaveChanges(Rock.Data.DbContext dbContext, EntityState state) { base.PreSaveChanges(dbContext, state); base.PostSaveChanges(dbContext); var entityTypeCache = EntityTypeCache.Get(EntityTypeId); var entityType = entityTypeCache.GetEntityType(); var entityService = Reflection.GetServiceForEntityType(entityType, dbContext); System.Reflection.MethodInfo getMethod = entityService.GetType().GetMethod("Get", new Type[] { typeof(int) }); var mergeObjectEntity = getMethod.Invoke(entityService, new object[] { EntityId }) as Rock.Data.IEntity; this.Name = mergeObjectEntity.ToString(); }
/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, EntityState state) { if (ImageId.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(( RockContext )dbContext); var binaryFile = binaryFileService.Get(ImageId.Value); if (binaryFile != null && binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } } base.PreSaveChanges(dbContext, state); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(System.Data.Entity.EntityState entityState, Rock.Data.DbContext dbContext) { var group = this.Group ?? new GroupService(new RockContext()).GetNoTracking(this.GroupId); if (group != null) { var groupType = GroupTypeCache.Get(group.GroupTypeId, (RockContext)dbContext); if (group.IsSecurityRole || groupType?.Guid == Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid()) { RoleCache.FlushItem(group.Id); Rock.Security.Authorization.Clear(); } } }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { var cachedDefinedValues = DefinedTypeCache.Get(this.Id, ( RockContext )dbContext)?.DefinedValues; if (cachedDefinedValues?.Any() == true) { foreach (var cachedDefinedValue in cachedDefinedValues) { DefinedValueCache.UpdateCachedEntity(cachedDefinedValue.Id, EntityState.Detached); } } DefinedTypeCache.UpdateCachedEntity(this.Id, entityState); }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, DbEntityEntry entry) { var rockContext = (RockContext)dbContext; BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(BinaryFileId); HistoryChangeList = new History.HistoryChangeList(); switch (entry.State) { case EntityState.Added: { // if there is an binaryfile (image) associated with this, make sure that it is flagged as IsTemporary=False if (binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } HistoryChangeList.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Image"); break; } case EntityState.Modified: { // if there is an binaryfile (image) associated with this, make sure that it is flagged as IsTemporary=False if (binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } HistoryChangeList.AddChange(History.HistoryVerb.Modify, History.HistoryChangeType.Record, "Image"); break; } case EntityState.Deleted: { // if deleting, and there is an binaryfile (image) associated with this, make sure that it is flagged as IsTemporary=true // so that it'll get cleaned up if (!binaryFile.IsTemporary) { binaryFile.IsTemporary = true; } HistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Image"); break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, EntityState state) { if (state == EntityState.Deleted) { var rockContext = dbContext as RockContext; // manually clear any registrations using this workflow type foreach (var template in new RegistrationTemplateService(rockContext) .Queryable() .Where(r => r.RegistrationWorkflowTypeId.HasValue && r.RegistrationWorkflowTypeId.Value == this.Id)) { template.RegistrationWorkflowTypeId = null; } foreach (var instance in new RegistrationInstanceService(rockContext) .Queryable() .Where(r => r.RegistrationWorkflowTypeId.HasValue && r.RegistrationWorkflowTypeId.Value == this.Id)) { instance.RegistrationWorkflowTypeId = null; } /* * 7/6/2020 - JH * The deletion of the Workflow object graph is accomplished by a combination of SQL cascade deletes and * PreSaveChanges() implementations. * * When a WorkflowType is deleted, any child Workflows will be cascade-deleted. Most children of the deleted * Workflows will also be cascade-deleted, with the exception of any ConnectionRequestWorkflow records. Therefore, * we need to manually delete those here in order to prevent foreign key violations within the database. * * Reason: GitHub Issue #4068 * https://github.com/SparkDevNetwork/Rock/issues/4068#issuecomment-648908315 */ var connectionRequestWorkflows = new ConnectionRequestWorkflowService(rockContext) .Queryable() .Where(c => c.Workflow.WorkflowTypeId == this.Id); if (connectionRequestWorkflows.Any()) { dbContext.BulkDelete(connectionRequestWorkflows); } } base.PreSaveChanges(dbContext, state); }
/// <summary> /// Queries the database by guid with context. /// </summary> /// <param name="guid">The unique identifier.</param> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private static T QueryDbWithContext(Guid guid, DbContext rockContext) { var service = new Service <TT>(rockContext); var entity = service.Get(guid); if (entity == null) { return(default(T)); } var value = new T(); value.SetFromEntity(entity); return(value); }
/// <summary> /// Saves to attribute historical value table. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry">The entry.</param> /// <param name="attributeCache">The attribute cache.</param> /// <param name="saveToHistoryTable">if set to <c>true</c> [save to history table].</param> protected void SaveToHistoryTable(Rock.Data.DbContext dbContext, DbEntityEntry entry, AttributeCache attributeCache, bool saveToHistoryTable) { this.PostSaveAttributeValueHistoryCurrent = false; var oldValue = GetHistoryOldValue(entry); var newValue = GetHistoryNewValue(entry.State); if (oldValue == newValue || !attributeCache.EnableHistory) { return; } var formattedOldValue = GetHistoryFormattedValue(oldValue, attributeCache); // value changed and attribute.EnableHistory = true, so flag PostSaveAttributeValueHistoryCurrent this.PostSaveAttributeValueHistoryCurrent = true; var attributeValueHistoricalService = new AttributeValueHistoricalService(dbContext as RockContext); if (this.Id < 1) { return; } // this is an existing AttributeValue, so fetch the AttributeValue that is currently marked as CurrentRow for this attribute value (if it exists) bool hasAttributeValueHistoricalCurrentRow = attributeValueHistoricalService.Queryable().Where(a => a.AttributeValueId == this.Id && a.CurrentRowIndicator == true).Any(); if (!hasAttributeValueHistoricalCurrentRow) { // this is an existing AttributeValue but there isn't a CurrentRow AttributeValueHistorical for this AttributeValue yet, so create it off of the OriginalValues AttributeValueHistorical attributeValueHistoricalPreviousCurrentRow = new AttributeValueHistorical { AttributeValueId = this.Id, Value = oldValue, ValueFormatted = formattedOldValue, ValueAsNumeric = entry.OriginalValues["ValueAsNumeric"] as decimal?, ValueAsDateTime = entry.OriginalValues["ValueAsDateTime"] as DateTime?, ValueAsBoolean = entry.OriginalValues["ValueAsBoolean"] as bool?, ValueAsPersonId = entry.OriginalValues["ValueAsPersonId"] as int?, EffectiveDateTime = entry.OriginalValues["ModifiedDateTime"] as DateTime? ?? RockDateTime.Now, CurrentRowIndicator = true, ExpireDateTime = HistoricalTracking.MaxExpireDateTime }; attributeValueHistoricalService.Add(attributeValueHistoricalPreviousCurrentRow); } }
/// <summary> /// Queries the database by guid. /// </summary> /// <param name="guid">The unique identifier.</param> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private static T QueryDb(Guid guid, DbContext rockContext) { if (guid.IsEmpty()) { return(default(T)); } if (rockContext != null) { return(QueryDbWithContext(guid, rockContext)); } using (var newRockContext = new RockContext()) { return(QueryDbWithContext(guid, newRockContext)); } }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { // Make sure CampusCache.All is cached using the dbContext (to avoid deadlock if snapshot isolation is disabled) var campusId = this.GetCampusId(dbContext as RockContext); // CampusCache has a CampusLocation that could get stale when Location changes, so refresh the CampusCache for this location's Campus if (this.CampusId.HasValue) { CampusCache.UpdateCachedEntity(this.CampusId.Value, EntityState.Detached); } // and also refresh the CampusCache for any Campus that uses this location foreach (var campus in CampusCache.All(dbContext as RockContext).Where(c => c.LocationId == this.Id)) { CampusCache.UpdateCachedEntity(campus.Id, EntityState.Detached); } }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.Infrastructure.DbEntityEntry entry) { var rockContext = ( RockContext )dbContext; BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(BinaryFileId); switch (entry.State) { case System.Data.Entity.EntityState.Added: { // if there is an binaryfile (attachment) associated with this, make sure that it is flagged as IsTemporary=False if (binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } break; } case System.Data.Entity.EntityState.Modified: { // if there is an binaryfile (attachment) associated with this, make sure that it is flagged as IsTemporary=False if (binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } break; } case System.Data.Entity.EntityState.Deleted: { // if deleting, and there is an binaryfile (attachment) associated with this, make sure that it is flagged as IsTemporary=true // so that it'll get cleaned up if (!binaryFile.IsTemporary) { binaryFile.IsTemporary = true; } break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChangeList = new History.HistoryChangeList(); switch (entry.State) { case EntityState.Added: { History.EvaluateChange(HistoryChangeList, "Account Number", string.Empty, AccountNumberMasked); History.EvaluateChange(HistoryChangeList, "Currency Type", (int?)null, CurrencyTypeValue, CurrencyTypeValueId); History.EvaluateChange(HistoryChangeList, "Credit Card Type", (int?)null, CreditCardTypeValue, CreditCardTypeValueId); History.EvaluateChange(HistoryChangeList, "Name On Card", string.Empty, AccountNumberMasked, true); History.EvaluateChange(HistoryChangeList, "Expiration Month", string.Empty, ExpirationMonthEncrypted, true); History.EvaluateChange(HistoryChangeList, "Expiration Year", string.Empty, ExpirationYearEncrypted, true); History.EvaluateChange(HistoryChangeList, "Billing Location", string.Empty, History.GetValue <Location>(BillingLocation, BillingLocationId, rockContext)); break; } case EntityState.Modified: case EntityState.Deleted: { History.EvaluateChange(HistoryChangeList, "Account Number", entry.OriginalValues["AccountNumberMasked"].ToStringSafe(), AccountNumberMasked); History.EvaluateChange(HistoryChangeList, "Currency Type", entry.OriginalValues["CurrencyTypeValueId"].ToStringSafe().AsIntegerOrNull(), CurrencyTypeValue, CurrencyTypeValueId); History.EvaluateChange(HistoryChangeList, "Credit Card Type", entry.OriginalValues["CreditCardTypeValueId"].ToStringSafe().AsIntegerOrNull(), CreditCardTypeValue, CreditCardTypeValueId); History.EvaluateChange(HistoryChangeList, "Name On Card", entry.OriginalValues["AccountNumberMasked"].ToStringSafe(), AccountNumberMasked, true); History.EvaluateChange(HistoryChangeList, "Expiration Month", entry.OriginalValues["ExpirationMonthEncrypted"].ToStringSafe(), ExpirationMonthEncrypted, true); History.EvaluateChange(HistoryChangeList, "Expiration Year", entry.OriginalValues["ExpirationYearEncrypted"].ToStringSafe(), ExpirationYearEncrypted, true); History.EvaluateChange(HistoryChangeList, "Billing Location", History.GetValue <Location>(null, entry.OriginalValues["BillingLocationId"].ToStringSafe().AsIntegerOrNull(), rockContext), History.GetValue <Location>(BillingLocation, BillingLocationId, rockContext)); break; } } if (entry.State == EntityState.Added || entry.State == EntityState.Modified) { // Ensure that CurrencyTypeValueId is set. The UI tries to prevent it, but just in case, if it isn't, set it to Unknown if (!this.CurrencyTypeValueId.HasValue) { this.CurrencyTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_UNKNOWN.AsGuid())?.Id; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(System.Data.Entity.EntityState entityState, Rock.Data.DbContext dbContext) { // If the group changed, and it was a security group, flush the security for the group Guid?originalGroupTypeGuid = null; Guid groupTypeScheduleRole = Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid(); if (_originalGroupTypeId.HasValue && _originalGroupTypeId != this.GroupTypeId) { originalGroupTypeGuid = GroupTypeCache.Get(_originalGroupTypeId.Value, (RockContext)dbContext)?.Guid; } var groupTypeGuid = GroupTypeCache.Get(this.GroupTypeId, (RockContext)dbContext)?.Guid; if (this.IsSecurityRole || (_originalIsSecurityRole == true) || (groupTypeGuid == groupTypeScheduleRole) || (originalGroupTypeGuid == groupTypeScheduleRole)) { RoleCache.FlushItem(this.Id); } }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, DbEntityEntry entry) { var rockContext = ( RockContext )dbContext; HistoryChangeList = new History.HistoryChangeList(); switch (entry.State) { case EntityState.Added: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); HistoryChangeList.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, acct).SetNewValue(Amount.FormatAsCurrency()); break; } case EntityState.Modified: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); int?accountId = this.Account != null ? this.Account.Id : this.AccountId; int?origAccountId = entry.OriginalValues["AccountId"].ToStringSafe().AsIntegerOrNull(); if (!accountId.Equals(origAccountId)) { History.EvaluateChange(HistoryChangeList, "Account", History.GetValue <FinancialAccount>(null, origAccountId, rockContext), acct); } History.EvaluateChange(HistoryChangeList, acct, entry.OriginalValues["Amount"].ToStringSafe().AsDecimal().FormatAsCurrency(), Amount.FormatAsCurrency()); History.EvaluateChange(HistoryChangeList, acct, entry.OriginalValues["FeeAmount"].ToStringSafe().AsDecimal().FormatAsCurrency(), FeeAmount.FormatAsCurrency()); History.EvaluateChange(HistoryChangeList, acct, entry.OriginalValues["FeeCoverageAmount"].ToStringSafe().AsDecimal().FormatAsCurrency(), FeeCoverageAmount.FormatAsCurrency()); break; } case EntityState.Deleted: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); HistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, acct).SetOldValue(Amount.FormatAsCurrency()); break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { ChildGroupTypes.Clear(); // manually delete any grouprequirements of this grouptype since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(dbContext as RockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupTypeId.HasValue && a.GroupTypeId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } } // clean up the index if (state == System.Data.Entity.EntityState.Deleted && IsIndexEnabled) { this.DeleteIndexedDocumentsByGroupType(this.Id); } else if (state == System.Data.Entity.EntityState.Modified) { // check if indexing is enabled var changeEntry = dbContext.ChangeTracker.Entries <GroupType>().Where(a => a.Entity == this).FirstOrDefault(); if (changeEntry != null) { var originalIndexState = (bool)changeEntry.OriginalValues["IsIndexEnabled"]; if (originalIndexState == true && IsIndexEnabled == false) { // clear out index items this.DeleteIndexedDocumentsByGroupType(Id); } else if (IsIndexEnabled == true) { // if indexing is enabled then bulk index - needed as an attribute could have changed from IsIndexed BulkIndexDocumentsByGroupType(Id); } } } base.PreSaveChanges(dbContext, state); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { //var oldPageCache = PageCache.Get( this.Id, (RockContext)dbContext ); //if ( oldPageCache != null ) //{ // oldPageCache.RemoveChildPages(); //} PageCache.UpdateCachedEntity(this.Id, entityState); if (this.ParentPageId.HasValue) { PageCache.UpdateCachedEntity(this.ParentPageId.Value, EntityState.Detached); } if (_originalParentPageId.HasValue && _originalParentPageId != this.ParentPageId) { PageCache.UpdateCachedEntity(_originalParentPageId.Value, EntityState.Detached); } }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.Infrastructure.DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChanges = new List <string>(); switch (entry.State) { case System.Data.Entity.EntityState.Added: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); HistoryChanges.Add(string.Format("Added <span class='field-name'>{0}</span> account for <span class='field-value'>{1}</span>.", acct, Amount.FormatAsCurrency())); break; } case System.Data.Entity.EntityState.Modified: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); int?accountId = this.Account != null ? this.Account.Id : this.AccountId; int?origAccountId = entry.OriginalValues["AccountId"].ToStringSafe().AsIntegerOrNull(); if (!accountId.Equals(origAccountId)) { History.EvaluateChange(HistoryChanges, "Account", History.GetValue <FinancialAccount>(null, origAccountId, rockContext), acct); } History.EvaluateChange(HistoryChanges, acct, entry.OriginalValues["Amount"].ToStringSafe().AsDecimal().FormatAsCurrency(), Amount.FormatAsCurrency()); break; } case System.Data.Entity.EntityState.Deleted: { string acct = History.GetValue <FinancialAccount>(this.Account, this.AccountId, rockContext); HistoryChanges.Add(string.Format("Removed <span class='field-name'>{0}</span> account for <span class='field-value'>{1}</span>.", acct, Amount.FormatAsCurrency())); break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Delete the old binary file for UPDATE and DELETE and make sure new binary files are not temporary /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry">The entry.</param> protected void PreSaveBinaryFile(Rock.Data.DbContext dbContext, DbEntityEntry entry) { Guid?newBinaryFileGuid = null; Guid?oldBinaryFileGuid = null; if (entry.State == EntityState.Added || entry.State == EntityState.Modified) { newBinaryFileGuid = Value.AsGuidOrNull(); } if (entry.State == EntityState.Modified || entry.State == EntityState.Deleted) { oldBinaryFileGuid = entry.OriginalValues["Value"]?.ToString().AsGuidOrNull(); } if (oldBinaryFileGuid.HasValue) { if (!newBinaryFileGuid.HasValue || !newBinaryFileGuid.Value.Equals(oldBinaryFileGuid.Value)) { var deleteBinaryFileAttributeMsg = new DeleteBinaryFileAttribute.Message() { BinaryFileGuid = oldBinaryFileGuid.Value }; deleteBinaryFileAttributeMsg.Send(); } } if (newBinaryFileGuid.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(( RockContext )dbContext); var binaryFile = binaryFileService.Get(newBinaryFileGuid.Value); if (binaryFile != null && binaryFile.IsTemporary) { binaryFile.IsTemporary = false; } } }
/// <summary> /// Method that will be called on an entity immediately after the item is saved by context /// </summary> /// <param name="dbContext">The database context.</param> public override void PostSaveChanges(Rock.Data.DbContext dbContext) { // ensure any attachments have the binaryFile.IsTemporary set to False var attachmentBinaryFilesIds = this.Attachments.Select(a => a.BinaryFileId).ToList(); if (attachmentBinaryFilesIds.Any()) { using (var rockContext = new RockContext()) { var temporaryBinaryFiles = new BinaryFileService(rockContext).GetByIds(attachmentBinaryFilesIds).Where(a => a.IsTemporary == true).ToList(); { foreach (var binaryFile in temporaryBinaryFiles) { binaryFile.IsTemporary = false; } } rockContext.SaveChanges(); } } base.PostSaveChanges(dbContext); }
/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { // manually delete any grouprequirements of this group since it can't be cascade deleted var groupRequirementService = new GroupRequirementService(dbContext as RockContext); var groupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId == this.Id).ToList(); if (groupRequirements.Any()) { groupRequirementService.DeleteRange(groupRequirements); } // manually set any attendance search group ids to null var attendanceService = new AttendanceService(dbContext as RockContext); foreach (var attendance in attendanceService.Queryable() .Where(a => a.SearchResultGroupId.HasValue && a.SearchResultGroupId.Value == this.Id)) { attendance.SearchResultGroupId = null; } } }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry">The entry.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, DbEntityEntry entry) { var attributeCache = AttributeCache.Get(this.AttributeId); if (attributeCache != null) { // Check to see if this attribute value if for a File, Image, or BackgroundCheck field type. // If so then delete the old binary file for UPDATE and DELETE and make sure new binary files are not temporary // This path needs to happen for FieldTypes that actually upload/create a file but not for FieldTypes that consist of already existing files. // This attribute value should not effect a file that anything could be using. // The Label field type is a list of existing labels so should not be included, but the image field type uploads a new file so we do want it included. // Don't use BinaryFileFieldType as that type of attribute's file can be used by more than one attribute var field = attributeCache.FieldType.Field; if (field != null && ( field is Field.Types.FileFieldType || field is Field.Types.ImageFieldType || field is Field.Types.BackgroundCheckFieldType)) { PreSaveBinaryFile(dbContext, entry); } // Check to see if this attribute value is for a StructureContentEditorFieldType. // If so then we need to detect any changes in the content blocks. if (field is Field.Types.StructureContentEditorFieldType) { PreSaveStructuredContent(dbContext, entry); } // Save to the historical table if history is enabled if (attributeCache.EnableHistory) { SaveToHistoryTable(dbContext, entry, attributeCache, true); } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext"></param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.Infrastructure.DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChanges = new List <string>(); switch (entry.State) { case System.Data.Entity.EntityState.Added: { History.EvaluateChange(HistoryChanges, "Account Number", string.Empty, AccountNumberMasked); History.EvaluateChange(HistoryChanges, "Currency Type", (int?)null, CurrencyTypeValue, CurrencyTypeValueId); History.EvaluateChange(HistoryChanges, "Credit Card Type", (int?)null, CreditCardTypeValue, CreditCardTypeValueId); History.EvaluateChange(HistoryChanges, "Name On Card", string.Empty, AccountNumberMasked, true); History.EvaluateChange(HistoryChanges, "Expiration Month", string.Empty, ExpirationMonthEncrypted, true); History.EvaluateChange(HistoryChanges, "Expiration Year", string.Empty, ExpirationYearEncrypted, true); History.EvaluateChange(HistoryChanges, "Billing Location", string.Empty, History.GetValue <Location>(BillingLocation, BillingLocationId, rockContext)); break; } case System.Data.Entity.EntityState.Modified: case System.Data.Entity.EntityState.Deleted: { History.EvaluateChange(HistoryChanges, "Account Number", entry.OriginalValues["AccountNumberMasked"].ToStringSafe(), AccountNumberMasked); History.EvaluateChange(HistoryChanges, "Currency Type", entry.OriginalValues["CurrencyTypeValueId"].ToStringSafe().AsIntegerOrNull(), CurrencyTypeValue, CurrencyTypeValueId); History.EvaluateChange(HistoryChanges, "Credit Card Type", entry.OriginalValues["CreditCardTypeValueId"].ToStringSafe().AsIntegerOrNull(), CreditCardTypeValue, CreditCardTypeValueId); History.EvaluateChange(HistoryChanges, "Name On Card", entry.OriginalValues["AccountNumberMasked"].ToStringSafe(), AccountNumberMasked, true); History.EvaluateChange(HistoryChanges, "Expiration Month", entry.OriginalValues["ExpirationMonthEncrypted"].ToStringSafe(), ExpirationMonthEncrypted, true); History.EvaluateChange(HistoryChanges, "Expiration Year", entry.OriginalValues["ExpirationYearEncrypted"].ToStringSafe(), ExpirationYearEncrypted, true); History.EvaluateChange(HistoryChanges, "Billing Location", History.GetValue <Location>(null, entry.OriginalValues["BillingLocationId"].ToStringSafe().AsIntegerOrNull(), rockContext), History.GetValue <Location>(BillingLocation, BillingLocationId, rockContext)); break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Pres the save changes. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.EntityState state) { if (state == System.Data.Entity.EntityState.Deleted) { // manually clear any registrations using this workflow type foreach (var template in new RegistrationTemplateService(dbContext as RockContext) .Queryable() .Where(r => r.RegistrationWorkflowTypeId.HasValue && r.RegistrationWorkflowTypeId.Value == this.Id)) { template.RegistrationWorkflowTypeId = null; } foreach (var instance in new RegistrationInstanceService(dbContext as RockContext) .Queryable() .Where(r => r.RegistrationWorkflowTypeId.HasValue && r.RegistrationWorkflowTypeId.Value == this.Id)) { instance.RegistrationWorkflowTypeId = null; } } }
/// <summary> /// Method that will be called on an entity immediately before the item is saved by context /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="state">The state.</param> public override void PreSaveChanges( Rock.Data.DbContext dbContext, EntityState state ) { if ( _logEntries != null ) { if ( _logEntries.Any() ) { if ( dbContext is RockContext ) { var workflowLogService = new WorkflowLogService( ( dbContext as RockContext ) ); foreach ( var logEntry in _logEntries ) { workflowLogService.Add( new WorkflowLog { LogDateTime = logEntry.LogDateTime, LogText = logEntry.LogText, WorkflowId = this.Id } ); } _logEntries.Clear(); } } } // Set the workflow number if ( state == EntityState.Added ) { int maxNumber = new WorkflowService( dbContext as RockContext ) .Queryable().AsNoTracking() .Where( w => w.WorkflowTypeId == this.WorkflowTypeId ) .Max( w => (int?)w.WorkflowIdNumber ) ?? 0; this.WorkflowIdNumber = maxNumber + 1; } if ( state == EntityState.Deleted ) { DeleteConnectionRequestWorkflows( dbContext ); } base.PreSaveChanges( dbContext, state ); }
/// <summary> /// Pres the save. /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry"></param> public override void PreSaveChanges(Rock.Data.DbContext dbContext, System.Data.Entity.Infrastructure.DbEntityEntry entry) { var rockContext = (RockContext)dbContext; HistoryChangeList = new History.HistoryChangeList(); BatchHistoryChangeList = new Dictionary <int, History.HistoryChangeList> (); switch (entry.State) { case System.Data.Entity.EntityState.Added: { HistoryChangeList.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Transaction"); string person = History.GetValue <PersonAlias>(AuthorizedPersonAlias, AuthorizedPersonAliasId, rockContext); History.EvaluateChange(HistoryChangeList, "Authorized Person", string.Empty, person); History.EvaluateChange(HistoryChangeList, "Batch", string.Empty, History.GetValue <FinancialBatch>(Batch, BatchId, rockContext)); History.EvaluateChange(HistoryChangeList, "Gateway", string.Empty, History.GetValue <FinancialGateway>(FinancialGateway, FinancialGatewayId, rockContext)); History.EvaluateChange(HistoryChangeList, "Transaction Date/Time", (DateTime?)null, TransactionDateTime); History.EvaluateChange(HistoryChangeList, "Transaction Code", string.Empty, TransactionCode); History.EvaluateChange(HistoryChangeList, "Summary", string.Empty, Summary); History.EvaluateChange(HistoryChangeList, "Type", (int?)null, TransactionTypeValue, TransactionTypeValueId); History.EvaluateChange(HistoryChangeList, "Source", (int?)null, SourceTypeValue, SourceTypeValueId); History.EvaluateChange(HistoryChangeList, "Scheduled Transaction Id", (int?)null, ScheduledTransactionId); History.EvaluateChange(HistoryChangeList, "Processed By", string.Empty, History.GetValue <PersonAlias>(ProcessedByPersonAlias, ProcessedByPersonAliasId, rockContext)); History.EvaluateChange(HistoryChangeList, "Processed Date/Time", (DateTime?)null, ProcessedDateTime); History.EvaluateChange(HistoryChangeList, "Status", string.Empty, Status); History.EvaluateChange(HistoryChangeList, "Status Message", string.Empty, StatusMessage); int?batchId = Batch != null ? Batch.Id : BatchId; if (batchId.HasValue) { var batchChanges = new History.HistoryChangeList(); batchChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Transaction").SetNewValue($"{this.TotalAmount.FormatAsCurrency()} for {person}"); BatchHistoryChangeList.Add(batchId.Value, batchChanges); } break; } case System.Data.Entity.EntityState.Modified: { string origPerson = History.GetValue <PersonAlias>(null, entry.OriginalValues["AuthorizedPersonAliasId"].ToStringSafe().AsIntegerOrNull(), rockContext); string person = History.GetValue <PersonAlias>(AuthorizedPersonAlias, AuthorizedPersonAliasId, rockContext); History.EvaluateChange(HistoryChangeList, "Authorized Person", origPerson, person); int?origBatchId = entry.OriginalValues["BatchId"].ToStringSafe().AsIntegerOrNull(); int?batchId = Batch != null ? Batch.Id : BatchId; if (!batchId.Equals(origBatchId)) { string origBatch = History.GetValue <FinancialBatch>(null, origBatchId, rockContext); string batch = History.GetValue <FinancialBatch>(Batch, BatchId, rockContext); History.EvaluateChange(HistoryChangeList, "Batch", origBatch, batch); } int?origGatewayId = entry.OriginalValues["FinancialGatewayId"].ToStringSafe().AsIntegerOrNull(); if (!FinancialGatewayId.Equals(origGatewayId)) { History.EvaluateChange(HistoryChangeList, "Gateway", History.GetValue <FinancialGateway>(null, origGatewayId, rockContext), History.GetValue <FinancialGateway>(FinancialGateway, FinancialGatewayId, rockContext)); } History.EvaluateChange(HistoryChangeList, "Transaction Date/Time", entry.OriginalValues["TransactionDateTime"].ToStringSafe().AsDateTime(), TransactionDateTime); History.EvaluateChange(HistoryChangeList, "Transaction Code", entry.OriginalValues["TransactionCode"].ToStringSafe(), TransactionCode); History.EvaluateChange(HistoryChangeList, "Summary", entry.OriginalValues["Summary"].ToStringSafe(), Summary); History.EvaluateChange(HistoryChangeList, "Type", entry.OriginalValues["TransactionTypeValueId"].ToStringSafe().AsIntegerOrNull(), TransactionTypeValue, TransactionTypeValueId); History.EvaluateChange(HistoryChangeList, "Source", entry.OriginalValues["SourceTypeValueId"].ToStringSafe().AsIntegerOrNull(), SourceTypeValue, SourceTypeValueId); History.EvaluateChange(HistoryChangeList, "Scheduled Transaction Id", entry.OriginalValues["ScheduledTransactionId"].ToStringSafe().AsIntegerOrNull(), ScheduledTransactionId); History.EvaluateChange(HistoryChangeList, "Processed By", entry.OriginalValues["ProcessedByPersonAliasId"].ToStringSafe().AsIntegerOrNull(), ProcessedByPersonAlias, ProcessedByPersonAliasId, rockContext); History.EvaluateChange(HistoryChangeList, "Processed Date/Time", entry.OriginalValues["ProcessedDateTime"].ToStringSafe().AsDateTime(), ProcessedDateTime); History.EvaluateChange(HistoryChangeList, "Status", entry.OriginalValues["Status"].ToStringSafe(), Status); History.EvaluateChange(HistoryChangeList, "Status Message", entry.OriginalValues["StatusMessage"].ToStringSafe(), StatusMessage); if (!batchId.Equals(origBatchId)) { var batchChanges = new History.HistoryChangeList(); if (origBatchId.HasValue) { batchChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Transaction").SetOldValue($"{this.TotalAmount.FormatAsCurrency()} for {person}"); } if (batchId.HasValue) { batchChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Transaction").SetNewValue($"{this.TotalAmount.FormatAsCurrency()} for {person}"); } BatchHistoryChangeList.Add(batchId.Value, batchChanges); } else { if (batchId.HasValue) { var batchChanges = new History.HistoryChangeList(); batchChanges.AddChange(History.HistoryVerb.Modify, History.HistoryChangeType.Record, $"Transaction Id:{Id}"); BatchHistoryChangeList.Add(batchId.Value, batchChanges); } } break; } case System.Data.Entity.EntityState.Deleted: { HistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Transaction"); int?batchId = Batch != null ? Batch.Id : BatchId; if (batchId.HasValue) { string batch = History.GetValue <FinancialBatch>(Batch, BatchId, rockContext); string person = History.GetValue <PersonAlias>(AuthorizedPersonAlias, AuthorizedPersonAliasId, rockContext); var batchChanges = new History.HistoryChangeList(); batchChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Transaction").SetOldValue($"{this.TotalAmount.FormatAsCurrency()} for {person}"); BatchHistoryChangeList.Add(batchId.Value, batchChanges); } // since images have a cascade delete relationship, make sure the PreSaveChanges gets called var childImages = new FinancialTransactionImageService(dbContext as RockContext).Queryable().Where(a => a.TransactionId == this.Id); foreach (var image in childImages) { image.PreSaveChanges(dbContext, entry.State); } break; } } base.PreSaveChanges(dbContext, entry); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { AttributeCache.UpdateCachedEntity(this.Id, entityState); AttributeCache.UpdateCacheEntityAttributes(this, entityState); int? entityTypeId; string entityTypeQualifierColumn; string entityTypeQualifierValue; if (entityState == EntityState.Deleted) { entityTypeId = originalEntityTypeId; entityTypeQualifierColumn = originalEntityTypeQualifierColumn; entityTypeQualifierValue = originalEntityTypeQualifierValue; } else { entityTypeId = this.EntityTypeId; entityTypeQualifierColumn = this.EntityTypeQualifierColumn; entityTypeQualifierValue = this.EntityTypeQualifierValue; } if ((!entityTypeId.HasValue || entityTypeId.Value == 0) && string.IsNullOrEmpty(entityTypeQualifierColumn) && string.IsNullOrEmpty(entityTypeQualifierValue)) { GlobalAttributesCache.Remove(); } if ((!entityTypeId.HasValue || entityTypeId.Value == 0) && entityTypeQualifierColumn == Attribute.SYSTEM_SETTING_QUALIFIER && string.IsNullOrEmpty(entityTypeQualifierValue)) { Rock.Web.SystemSettings.Remove(); } if (entityTypeId.HasValue) { if (entityTypeId == EntityTypeCache.GetId <Block>()) { // Update BlockTypes/Blocks that reference this attribute if (entityTypeQualifierColumn.Equals("BlockTypeId", StringComparison.OrdinalIgnoreCase)) { int?blockTypeId = entityTypeQualifierValue.AsIntegerOrNull(); if (blockTypeId.HasValue) { BlockTypeCache.FlushItem(blockTypeId.Value); foreach (var blockId in new BlockService(dbContext as RockContext).GetByBlockTypeId(blockTypeId.Value).Select(a => a.Id).ToList()) { BlockCache.FlushItem(blockId); } } } } else if (entityTypeId == EntityTypeCache.GetId <DefinedValue>()) { // Update DefinedTypes/DefinedValues that reference this attribute if (entityTypeQualifierColumn.Equals("DefinedTypeId", StringComparison.OrdinalIgnoreCase)) { int?definedTypeId = entityTypeQualifierValue.AsIntegerOrNull(); if (definedTypeId.HasValue) { DefinedTypeCache.FlushItem(definedTypeId.Value); foreach (var definedValueId in new DefinedValueService(dbContext as RockContext).GetByDefinedTypeId(definedTypeId.Value).Select(a => a.Id).ToList()) { DefinedValueCache.FlushItem(definedValueId); } } } } else if (entityTypeId == EntityTypeCache.GetId <WorkflowActivityType>()) { if (entityTypeQualifierColumn.Equals("ActivityTypeId", StringComparison.OrdinalIgnoreCase)) { int?activityTypeId = entityTypeQualifierValue.AsIntegerOrNull(); if (activityTypeId.HasValue) { WorkflowActivityTypeCache.FlushItem(activityTypeId.Value); } } } else if (entityTypeId == EntityTypeCache.GetId <GroupType>()) { if (entityTypeQualifierColumn.Equals("Id", StringComparison.OrdinalIgnoreCase)) { int?groupTypeId = entityTypeQualifierValue.AsIntegerOrNull(); if (groupTypeId.HasValue) { GroupTypeCache.FlushItem(groupTypeId.Value); } } else if (entityTypeQualifierColumn.Equals("GroupTypePurposeValueId", StringComparison.OrdinalIgnoreCase)) { int?groupTypePurposeValueId = entityTypeQualifierValue.AsIntegerOrNull(); if (groupTypePurposeValueId.HasValue) { foreach (var groupTypeId in GroupTypeCache.All().Where(a => a.GroupTypePurposeValueId == groupTypePurposeValueId.Value).Select(a => a.Id).ToList()) { GroupTypeCache.FlushItem(groupTypeId); } } } } else if (entityTypeId.HasValue) { // some other EntityType. If it the EntityType has a CacheItem associated with it, clear out all the CachedItems of that type to ensure they have a clean read of the Attributes that were Added, Changed or Removed EntityTypeCache entityType = EntityTypeCache.Get(entityTypeId.Value, dbContext as RockContext); if (entityType?.HasEntityCache() == true) { entityType.ClearCachedItems(); } } } }
/// <summary> /// Updates the Created/Modified data for any model being created or modified /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="personAlias">The person alias.</param> /// <returns></returns> protected virtual List<ContextItem> RockPreSave( DbContext dbContext, PersonAlias personAlias ) { int? personAliasId = null; if ( personAlias != null ) { personAliasId = personAlias.Id; } var updatedItems = new List<ContextItem>(); foreach ( var entry in dbContext.ChangeTracker.Entries() .Where( c => c.Entity is IEntity && ( c.State == EntityState.Added || c.State == EntityState.Modified || c.State == EntityState.Deleted ) ) ) { // Cast entry as IEntity var entity = entry.Entity as IEntity; // Get the context item to track audits var contextItem = new ContextItem( entity, entry.State ); // If entity was added or modifed, update the Created/Modified fields if ( entry.State == EntityState.Added || entry.State == EntityState.Modified ) { if ( !TriggerWorkflows( entity, WorkflowTriggerType.PreSave, personAlias ) ) { return null; } if ( entry.Entity is IModel ) { var model = entry.Entity as IModel; model.PreSaveChanges( this, entry.State ); // Update Guid/Created/Modified person and times if ( entry.State == EntityState.Added ) { if ( !model.CreatedDateTime.HasValue ) { model.CreatedDateTime = RockDateTime.Now; } if ( !model.CreatedByPersonAliasId.HasValue ) { model.CreatedByPersonAliasId = personAliasId; } if ( model.Guid == Guid.Empty ) { model.Guid = Guid.NewGuid(); } model.ModifiedDateTime = RockDateTime.Now; model.ModifiedByPersonAliasId = personAliasId; } else if ( entry.State == EntityState.Modified ) { model.ModifiedDateTime = RockDateTime.Now; model.ModifiedByPersonAliasId = personAliasId; } } } else if ( entry.State == EntityState.Deleted ) { if ( !TriggerWorkflows( entity, WorkflowTriggerType.PreDelete, personAlias ) ) { return null; } } try { GetAuditDetails( dbContext, contextItem, personAliasId ); } catch (SystemException ex) { ExceptionLogService.LogException( ex, null ); } updatedItems.Add( contextItem ); } return updatedItems; }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(System.Data.Entity.EntityState entityState, Rock.Data.DbContext dbContext) { CategoryCache.UpdateCachedEntity(this.Id, entityState); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { BlockTypeCache.UpdateCachedEntity(this.Id, entityState); }
/// <summary> /// Updates the Created/Modified data for any model being created or modified /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="personAlias">The person alias.</param> /// <param name="enableAuditing">if set to <c>true</c> [enable auditing].</param> /// <returns></returns> protected virtual List<ContextItem> RockPreSave( DbContext dbContext, PersonAlias personAlias, bool enableAuditing = false ) { int? personAliasId = null; if ( personAlias != null ) { personAliasId = personAlias.Id; } var preSavedEntities = new HashSet<Guid>(); // First loop through all models calling the PreSaveChanges foreach ( var entry in dbContext.ChangeTracker.Entries() .Where( c => c.Entity is IEntity && ( c.State == EntityState.Added || c.State == EntityState.Modified || c.State == EntityState.Deleted ) ) ) { if ( entry.Entity is IModel ) { var model = entry.Entity as IModel; model.PreSaveChanges( this, entry ); if ( !preSavedEntities.Contains( model.Guid ) ) { preSavedEntities.Add( model.Guid ); } } } // Then loop again, as new models may have been added by PreSaveChanges events var updatedItems = new List<ContextItem>(); foreach ( var entry in dbContext.ChangeTracker.Entries() .Where( c => c.Entity is IEntity && ( c.State == EntityState.Added || c.State == EntityState.Modified || c.State == EntityState.Deleted ) ) ) { // Cast entry as IEntity var entity = entry.Entity as IEntity; // Get the context item to track audits var contextItem = new ContextItem( entity, entry ); // If entity was added or modified, update the Created/Modified fields if ( entry.State == EntityState.Added || entry.State == EntityState.Modified ) { // instead of passing "true" the trigger model and UI would support a // on-value-changed checkbox (or perhaps it should be the default/only behavior) // and its value would be passed in to the onValueChange if ( !TriggerWorkflows( contextItem, WorkflowTriggerType.PreSave, personAlias ) ) { return null; } if ( entry.Entity is IModel ) { var model = entry.Entity as IModel; if ( !preSavedEntities.Contains( model.Guid ) ) { model.PreSaveChanges( this, entry ); } // Update Guid/Created/Modified person and times if ( entry.State == EntityState.Added ) { if ( !model.CreatedDateTime.HasValue ) { model.CreatedDateTime = RockDateTime.Now; } if ( !model.CreatedByPersonAliasId.HasValue ) { model.CreatedByPersonAliasId = personAliasId; } if ( model.Guid == Guid.Empty ) { model.Guid = Guid.NewGuid(); } model.ModifiedDateTime = RockDateTime.Now; model.ModifiedByPersonAliasId = personAliasId; } else if ( entry.State == EntityState.Modified ) { model.ModifiedDateTime = RockDateTime.Now; model.ModifiedByPersonAliasId = personAliasId; } } } else if ( entry.State == EntityState.Deleted ) { if ( !TriggerWorkflows( contextItem, WorkflowTriggerType.PreDelete, personAlias ) ) { return null; } } if ( enableAuditing ) { try { GetAuditDetails( dbContext, contextItem, personAliasId ); } catch ( SystemException ex ) { ExceptionLogService.LogException( ex, null ); } } updatedItems.Add( contextItem ); } return updatedItems; }
private static void GetAuditDetails( DbContext dbContext, ContextItem item, int? personAliasId ) { // Get the base class (not the proxy class) Type rockEntityType = item.Entity.GetType(); if ( rockEntityType.IsDynamicProxyType() ) { rockEntityType = rockEntityType.BaseType; } // Check to make sure class does not have [NotAudited] attribute if ( AuditClass( rockEntityType ) ) { var dbEntity = item.DbEntityEntry; var audit = item.Audit; PropertyInfo[] properties = rockEntityType.GetProperties(); foreach ( PropertyInfo propInfo in properties ) { // Check to make sure property does not have the [NotAudited] attribute if ( AuditProperty( propInfo ) ) { // If entire entity was added or deleted or this property was modified var dbPropertyEntry = dbEntity.Property( propInfo.Name ); if ( dbPropertyEntry != null && ( dbEntity.State == EntityState.Added || dbEntity.State == EntityState.Deleted || dbPropertyEntry.IsModified ) ) { var currentValue = dbEntity.State == EntityState.Deleted ? string.Empty : dbPropertyEntry.CurrentValue; var originalValue = dbEntity.State == EntityState.Added ? string.Empty : dbPropertyEntry.OriginalValue; var detail = new AuditDetail(); detail.Property = propInfo.Name; detail.CurrentValue = currentValue != null ? currentValue.ToString() : string.Empty; detail.OriginalValue = originalValue != null ? originalValue.ToString() : string.Empty; if ( detail.CurrentValue != detail.OriginalValue ) { audit.Details.Add( detail ); } } } } if ( audit.Details.Any() ) { var entityType = Rock.Web.Cache.EntityTypeCache.Read( rockEntityType ); if ( entityType != null ) { string title; try { title = item.Entity.ToString(); } catch { // ignore exception (Entity often overrides ToString() and we don't want that prevent the audit if it fails) title = null; } if ( string.IsNullOrWhiteSpace( title ) ) { title = entityType.FriendlyName ?? string.Empty; } audit.DateTime = RockDateTime.Now; audit.PersonAliasId = personAliasId; audit.EntityTypeId = entityType.Id; audit.EntityId = item.Entity.Id; audit.Title = title.Truncate( 195 ); } } } }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { StreakTypeAchievementTypeCache.UpdateCachedEntity(Id, entityState); }
/// <summary> /// Updates any Cache Objects that are associated with this entity /// </summary> /// <param name="entityState">State of the entity.</param> /// <param name="dbContext">The database context.</param> public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext) { LavaShortcodeCache.UpdateCachedEntity(this.Id, entityState); }