public override DbExpression Visit(DbScanExpression expression) { var column = ColumnAnnotationAttribute.GetColumnName <TrackDeletedBitAttribute>(expression.Target.ElementType); // var column = TrackDeletedBitAttribute.GetColumnName(expression.Target.ElementType); if (column != null) { var binding = expression.Bind(); return(binding .Filter(binding.VariableType.Variable(binding.VariableName) .Property(column) .NotEqual(DbExpression.FromBoolean(true)) .Or(binding.VariableType.Variable(binding.VariableName) .Property(column).IsNull()))); } else { return(base.Visit(expression)); } }
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) { if (interceptionContext.Result.DataSpace == DataSpace.SSpace && interceptionContext.DbContexts.All(con => con.GetType().GetCustomAttribute <TrackDisabledAttribute>() == null)) { #region Query var queryCommand = interceptionContext.Result as DbQueryCommandTree; if (queryCommand != null) { var newQuery = queryCommand.Query.Accept(new TrackingQueryVisitor()); interceptionContext.Result = new DbQueryCommandTree( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery); } #endregion #region Delete var deleteCommand = interceptionContext.Result as DbDeleteCommandTree; if (deleteCommand != null) { var bitColumn = ColumnAnnotationAttribute.GetColumnName <TrackDeletedBitAttribute>(deleteCommand.Target.VariableType.EdmType); var dateColumn = ColumnAnnotationAttribute.GetColumnName <TrackDeletedDateAttribute>(deleteCommand.Target.VariableType.EdmType); var identityColumn = ColumnAnnotationAttribute.GetColumnName <TrackDeletedIdentityAttribute>(deleteCommand.Target.VariableType.EdmType); var clauses = new List <DbModificationClause>(); if (bitColumn != null) { clauses.Add(DbExpressionBuilder.SetClause(deleteCommand.Target.Variable.Property(bitColumn), DbExpression.FromBoolean(true))); if (dateColumn != null) { clauses.Add(DbExpressionBuilder.SetClause(deleteCommand.Target.Variable.Property(dateColumn), DbExpression.FromDateTimeOffset(TimeZoneInfo.ConvertTime(timeProvider.NowOffsetted().Add(_dateTimeAdjustment), getCurrentTimeZoneFunction())))); } if (identityColumn != null) { clauses.Add(DbExpressionBuilder.SetClause(deleteCommand.Target.Variable.Property(identityColumn), DbExpression.FromString(getCurrentIdentityFunction()))); } } if (clauses.Count > 0) { //Add this constant clause to trace deletions on update command clauses.Add(DbExpressionBuilder.SetClause(DbExpressionBuilder.Constant(137), DbExpressionBuilder.Constant(137))); interceptionContext.Result = new DbUpdateCommandTree( deleteCommand.MetadataWorkspace, deleteCommand.DataSpace, deleteCommand.Target, deleteCommand.Predicate, clauses.AsReadOnly(), null); } } #endregion #region Insert var insertCommand = interceptionContext.Result as DbInsertCommandTree; if (insertCommand != null) { var dateColumn = ColumnAnnotationAttribute.GetColumnName <TrackCreatedDateAttribute>(insertCommand.Target.VariableType.EdmType); var identityColumn = ColumnAnnotationAttribute.GetColumnName <TrackCreatedIdentityAttribute>(insertCommand.Target.VariableType.EdmType); var clauses = insertCommand.SetClauses.ToList(); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedBitAttribute>(insertCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedDateAttribute>(insertCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedIdentityAttribute>(insertCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackModifiedDateAttribute>(insertCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackModifiedIdentityAttribute>(insertCommand.Target.VariableType.EdmType)); if (dateColumn != null) { AddOrReplaceClause(clauses, DbExpressionBuilder.SetClause(insertCommand.Target.Variable.Property(dateColumn), DbExpression.FromDateTimeOffset(TimeZoneInfo.ConvertTime(timeProvider.NowOffsetted().Add(_dateTimeAdjustment), getCurrentTimeZoneFunction())))); } if (identityColumn != null) { AddOrReplaceClause(clauses, DbExpressionBuilder.SetClause(insertCommand.Target.Variable.Property(identityColumn), DbExpression.FromString(getCurrentIdentityFunction()))); } if (dateColumn != null || (identityColumn != null)) { interceptionContext.Result = new DbInsertCommandTree( insertCommand.MetadataWorkspace, insertCommand.DataSpace, insertCommand.Target, clauses.AsReadOnly(), null); } } #endregion #region Update var updateCommand = interceptionContext.Result as DbUpdateCommandTree; if (updateCommand != null) { var dateColumn = ColumnAnnotationAttribute.GetColumnName <TrackModifiedDateAttribute>(updateCommand.Target.VariableType.EdmType); var identityColumn = ColumnAnnotationAttribute.GetColumnName <TrackModifiedIdentityAttribute>(updateCommand.Target.VariableType.EdmType); var clauses = updateCommand.SetClauses.ToList(); var traceDeleteionsClause = clauses.FirstOrDefault(c => ((DbSetClause)c).Property is DbConstantExpression && ((DbConstantExpression)((DbSetClause)c).Property).Value is int && ((int)((DbConstantExpression)((DbSetClause)c).Property).Value) == 137 && ((DbSetClause)c).Value is DbConstantExpression && ((DbConstantExpression)((DbSetClause)c).Value).Value is int && ((int)((DbConstantExpression)((DbSetClause)c).Value).Value) == 137 ); if (traceDeleteionsClause != null) { //This command is derived from a deletion operation clauses.Remove(traceDeleteionsClause); } else { RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedBitAttribute>(updateCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedDateAttribute>(updateCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackDeletedIdentityAttribute>(updateCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackCreatedDateAttribute>(updateCommand.Target.VariableType.EdmType)); RemoveClause(clauses, ColumnAnnotationAttribute.GetColumnName <TrackCreatedIdentityAttribute>(updateCommand.Target.VariableType.EdmType)); if (dateColumn != null) { AddOrReplaceClause(clauses, DbExpressionBuilder.SetClause(updateCommand.Target.Variable.Property(dateColumn), DbExpression.FromDateTimeOffset(TimeZoneInfo.ConvertTime(timeProvider.NowOffsetted().Add(_dateTimeAdjustment), getCurrentTimeZoneFunction())))); } if (identityColumn != null) { AddOrReplaceClause(clauses, DbExpressionBuilder.SetClause(updateCommand.Target.Variable.Property(identityColumn), DbExpression.FromString(getCurrentIdentityFunction()))); } } if (dateColumn != null || (identityColumn != null)) { interceptionContext.Result = new DbUpdateCommandTree( updateCommand.MetadataWorkspace, updateCommand.DataSpace, updateCommand.Target, updateCommand.Predicate, clauses.AsReadOnly(), null); } } #endregion } }