示例#1
0
        /// <summary>
        /// Sends this error as a notification email to the address in web.config as Error.Notification.Receiver.
        /// </summary>
        public static IEmailQueueItem SendAsNotification(this Exception error, string toNotify)
        {
            if (toNotify.IsEmpty())
            {
                return(null);
            }
            var email = EmailService.EmailQueueItemFactory();

            email.To      = toNotify;
            email.Subject = "Error In Application";
            email.Body    = "URL: " + HttpContext.Current?.Request?.Url + Environment.NewLine + "IP: " + HttpContext.Current?.Request?.UserHostAddress + Environment.NewLine + "User: " + ApplicationEventManager.GetCurrentUserId(HttpContext.Current?.User) + Environment.NewLine + error.ToLogString(error.Message);
            Database.Save(email);
            return(email);
        }
示例#2
0
        async Task DoSave(IEntity entity, SaveBehaviour behaviour)
        {
            var mode = entity.IsNew ? SaveMode.Insert : SaveMode.Update;

            var asEntity = entity as Entity;

            if (mode == SaveMode.Update && (asEntity._ClonedFrom?.IsStale == true) && AnyOpenTransaction())
            {
                throw new InvalidOperationException("This " + entity.GetType().Name + " instance in memory is out-of-date. " +
                                                    "A clone of it is already updated in the transaction. It is not allowed to update the same instance multiple times in a transaction, because then the earlier updates would be overwriten by the older state of the instance in memory. \r\n\r\n" +
                                                    @"BAD: 
Database.Update(myObject, x=> x.P1 = ...); // Note: this could also be nested inside another method that's called here instead.
Database.Update(myObject, x=> x.P2 = ...);

GOOD: 
Database.Update(myObject, x=> x.P1 = ...);
myObject = Database.Reload(myObject);
Database.Update(myObject, x=> x.P2 = ...);");
            }

            if (EntityManager.IsImmutable(entity))
            {
                throw new ArgumentException("An immutable record must be cloned before any modifications can be applied on it. " +
                                            $"Type={entity.GetType().FullName}, Id={entity.GetId()}.");
            }

            var dataProvider = GetProvider(entity);

            if (!IsSet(behaviour, SaveBehaviour.BypassValidation))
            {
                await EntityManager.RaiseOnValidating(entity as Entity, EventArgs.Empty);

                await entity.Validate();
            }
            else if (!dataProvider.SupportValidationBypassing())
            {
                throw new ArgumentException(dataProvider.GetType().Name + " does not support bypassing validation.");
            }

            #region Raise saving event

            if (!IsSet(behaviour, SaveBehaviour.BypassSaving))
            {
                var savingArgs = new System.ComponentModel.CancelEventArgs();
                await EntityManager.RaiseOnSaving(entity, savingArgs);

                if (savingArgs.Cancel)
                {
                    Cache.Current.Remove(entity);
                    return;
                }
            }

            #endregion

            if (!IsSet(behaviour, SaveBehaviour.BypassLogging) && !(entity is IApplicationEvent) &&
                Config.Get("Log.Record:Application:Events", defaultValue: true))
            {
                await ApplicationEventManager.RecordSave(entity, mode);
            }

            await dataProvider.Save(entity);

            Cache.Current.UpdateRowVersion(entity);

            if (mode == SaveMode.Update && asEntity?._ClonedFrom != null && AnyOpenTransaction())
            {
                asEntity._ClonedFrom.IsStale = true;
                asEntity.IsStale             = false;
            }

            if (mode == SaveMode.Insert)
            {
                EntityManager.SetSaved(entity);
            }

            Cache.Current.Remove(entity);

            if (Transaction.Current != null)
            {
                Transaction.Current.TransactionCompleted += (s, e) => { Cache.Current.Remove(entity); }
            }
            ;

            DbTransactionScope.Root?.OnTransactionCompleted(() => Cache.Current.Remove(entity));

            if (!(entity is IApplicationEvent))
            {
                await OnUpdated(entity);
            }

            if (!IsSet(behaviour, SaveBehaviour.BypassSaved))
            {
                await EntityManager.RaiseOnSaved(entity, new SaveEventArgs(mode));
            }

            // OnSaved event handler might have read the object again and put it in the cache, which would
            // create invalid CachedReference objects.
            Cache.Current.Remove(entity);
        }