Beispiel #1
0
        private static object CreateWithValues(PropertyValues values, Type type = null)
        {
            if (type == null)
            {
                type = typeof(T);
            }
            try
            {
                return(values.ToObject());
            }
            catch
            {
                var entity = Activator.CreateInstance(type);

                Debug.WriteLine(values.ToObject());
                foreach (var p in values.Properties)
                {
                    var name     = p.Name;
                    var value    = values.GetValue <object>(name);
                    var property = type.GetProperty(name);

                    if (value == null)
                    {
                        continue;
                    }

                    var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
                    property.SetValue(entity, Convert.ChangeType(value, propertyType), null);
                }
                return(entity);
            }
        }
        private static void AddHistoricalEntity(DbContext dbContext, PropertyValues originalValues, DateTimeOffset moment)
        {
            var original = Mapper.Map <THistoricalEntity>(originalValues.ToObject());

            original.ValidTo = moment;
            dbContext.Set <THistoricalEntity>().Add(original);
        }
        /// <summary>
        /// This method creates a changeset style model for Changes being made to the entity.
        /// This can be used to create audit logs or event queues in conjunction with IEntityOperationEventSink
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="entity"></param>
        /// <param name="operation"></param>
        /// <param name="currentValues"></param>
        /// <param name="originalValues"></param>
        /// <returns></returns>

        protected string TrackChange(T entity, EntityOperationType operation = EntityOperationType.Unknown, PropertyValues currentValues = null, PropertyValues originalValues = null, byte[] timestamp = null)
        {
            bool nonAuditable = typeof(INonAuditable).IsAssignableFrom(typeof(T));

            if (nonAuditable.Equals(false))
            {
                //create new AuditLog object
                AuditLog change = new AuditLog();

                try
                {
                    //define properties in object
                    change.Id       = Guid.NewGuid();
                    change.ObjectId = entity.Id;

                    change.CreatedBy = _caller.Identity == null ? entity.CreatedBy : _caller.Identity.Name;
                    change.CreatedOn = DateTime.UtcNow;

                    if (timestamp == null)
                    {
                        timestamp = new byte[1];
                    }

                    change.Timestamp = timestamp;
                    //name of service that is being changed
                    change.ServiceName = entity.ToString();
                    //name of how entity is being changed (Add, Update, Delete)
                    change.MethodName      = operation.ToString();
                    change.ParametersJson  = ""; //TODO: update to show parameters of method
                    change.ExceptionJson   = ""; //TODO: update to show any exceptions that arise
                    change.ChangedFromJson = (originalValues == null) ? null : JsonConvert.SerializeObject(originalValues.ToObject());
                    change.ChangedToJson   = (currentValues == null) ? null : JsonConvert.SerializeObject(currentValues.ToObject());

                    //add object to AuditLog data table
                    DbContext.Add(change);
                    DbContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    throw new EntityOperationException(ex);
                }

                //return audit log object as a string
                return(change.ToString());
            }

            return(new InvalidOperationException().Message);
        }
Beispiel #4
0
        protected async Task <IActionResult> HandleDbUpdateConcurrencyException(DbUpdateConcurrencyException ex)
        {
            EntityEntry    exceptionEntry = ex.Entries.Single();
            object         clientValues   = exceptionEntry.Entity;
            PropertyValues databaseEntry  = exceptionEntry.GetDatabaseValues();

            if (databaseEntry == null)
            {
                ModelState.AddModelError(string.Empty, $"Unable to update the table with the requested changes. The {typeof(TEntity).Name} was deleted by another user.");
            }
            else
            {
                object         databaseValues     = databaseEntry.ToObject();
                string         entityName         = databaseValues.GetType().Name;
                PropertyInfo[] databaseProperties = databaseValues.GetType().GetProperties(),
                clientProperties = clientValues.GetType().GetProperties();
                foreach (PropertyInfo databaseProperty in databaseProperties)
                {
                    // Don't report changes to the following fields
                    if (databaseProperty.Name == "RowVersion" ||
                        databaseProperty.Name == "UpdatedBy" ||
                        databaseProperty.Name == "UpdatedDate")
                    {
                        continue;
                    }

                    PropertyInfo clientProperty = clientProperties.Where(d =>
                                                                         d.Name == databaseProperty.Name &&
                                                                         d.PropertyType == databaseProperty.PropertyType)
                                                  .FirstOrDefault();
                    if (clientProperty != null)
                    {
                        object databaseValue = databaseProperty.GetValue(databaseValues),
                               clientValue   = clientProperty.GetValue(clientValues);
                        if (databaseValue != null &&
                            clientValue != null &&
                            !databaseValue.Equals(clientValue))
                        {
                            ModelState.AddModelError($"{entityName}.{databaseProperty.Name}", $"New table value: {databaseValue} / Your conflicting value: {clientValue}");
                        }
                    }
                }
                string userName, updatedBy, updatedDate;
                try
                {
                    updatedBy   = databaseProperties.First(p => p.Name == "UpdatedBy").GetValue(databaseValues).ToString();
                    updatedDate = databaseProperties.First(p => p.Name == "UpdatedDate").GetValue(databaseValues).ToString();
                    if (updatedBy == Ids.SystemUserId)
                    {
                        userName = "******";
                    }
                    else
                    {
                        User user = await _accountManager.GetUserByIdAsync(updatedBy);

                        userName = user.FullName;
                    }
                }
                catch
                {
                    userName    = "******";
                    updatedDate = "01/01/1900 00:00:00";
                }

                ModelState.AddModelError(string.Empty, "The record you attempted to update was modified " +
                                         $"by {userName} at {updatedDate} after you queried the " +
                                         "original values. The update operation was canceled and both the new values in the database " +
                                         "and the conflicting values you supplied have been provided.");
            }
            string message = $"A DbUpdateConcurrencyException occurred when attempting to update {typeof(TEntity).Name}\r\nThe following message was returned:\r\n" + string.Join(" | ", ModelState.Values
                                                                                                                                                                                  .SelectMany(v => v.Errors)
                                                                                                                                                                                  .Select(e => e.ErrorMessage));

            _logger.LogDebug(message);

            return(BadRequest(ModelState));
        }