/// <summary> /// In case of a delete command we always filter based on the tenantId /// </summary> private static void InterceptDeleteCommand(DbCommandTreeInterceptionContext interceptionContext, string tenantValue) { var deleteCommand = interceptionContext.Result as DbDeleteCommandTree; if (deleteCommand == null) { return; } var column = TenantAttribute.GetTenantColumnName(deleteCommand.Target.VariableType.EdmType); if (string.IsNullOrEmpty(column)) { return; } // Create the variable reference in order to create the property var variableReference = deleteCommand.Target.VariableType.Variable(deleteCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = variableReference.Property(column); var tenantIdWherePredicate = tenantProperty.Equal(DbExpression.FromString(tenantValue)); // The initial predicate is the sql where statement var initialPredicate = deleteCommand.Predicate; // Add to the initial statement the tenantId statement which translates in sql AND TenantId = 'value' var finalPredicate = initialPredicate.And(tenantIdWherePredicate); var newDeleteCommand = new DbDeleteCommandTree( deleteCommand.MetadataWorkspace, deleteCommand.DataSpace, deleteCommand.Target, finalPredicate); interceptionContext.Result = newDeleteCommand; }
/// <summary> /// In case of an update command we always filter based on the tenantId /// </summary> private static bool InterceptUpdate(DbCommandTreeInterceptionContext interceptionContext, string tenantValue) { var updateCommand = interceptionContext.Result as DbUpdateCommandTree; if (updateCommand == null) { return(false); } var column = TenantAttribute.GetTenantColumnName(updateCommand.Target.VariableType.EdmType); if (string.IsNullOrEmpty(column)) { return(false); } // Create the variable reference in order to create the property var variableReference = updateCommand.Target.VariableType.Variable(updateCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = variableReference.Property(column); // Create the tenantId where predicate, object representation of sql where tenantId = value statement var tenantIdWherePredicate = tenantProperty.Equal(DbExpression.FromString(tenantValue)); // Remove potential assignment of tenantId for extra safety var filteredSetClauses = updateCommand.SetClauses.Cast <DbSetClause>() .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column); // Construct the final clauses, object representation of sql insert command values var finalSetClauses = new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses)); // The initial predicate is the sql where statement var initialPredicate = updateCommand.Predicate; // Add to the initial statement the tenantId statement which translates in sql AND TenantId = 'value' var finalPredicate = initialPredicate.And(tenantIdWherePredicate); var newUpdateCommand = new DbUpdateCommandTree( updateCommand.MetadataWorkspace, updateCommand.DataSpace, updateCommand.Target, finalPredicate, finalSetClauses, updateCommand.Returning); interceptionContext.Result = newUpdateCommand; // True means an interception successfully happened so there is no need to continue return(true); }
/// <summary> /// In case of an insert command we always assign the correct value to the tenantId /// </summary> private static bool InterceptInsertCommand(DbCommandTreeInterceptionContext interceptionContext, string tenantValue) { var insertCommand = interceptionContext.Result as DbInsertCommandTree; if (insertCommand == null) { return(false); } var column = TenantAttribute.GetTenantColumnName(insertCommand.Target.VariableType.EdmType); if (string.IsNullOrEmpty(column)) { return(false); } // Create the variable reference in order to create the property var variableReference = insertCommand.Target.VariableType.Variable(insertCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = variableReference.Property(column); // Create the set clause, object representation of sql insert command var tenantSetClause = DbExpressionBuilder.SetClause(tenantProperty, DbExpression.FromString(tenantValue)); // Remove potential assignment of tenantId for extra safety var filteredSetClauses = insertCommand.SetClauses.Cast <DbSetClause>() .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column); // Construct the final clauses, object representation of sql insert command values var finalSetClauses = new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses) { tenantSetClause }); // Construct the new command var newInsertCommand = new DbInsertCommandTree( insertCommand.MetadataWorkspace, insertCommand.DataSpace, insertCommand.Target, finalSetClauses, insertCommand.Returning); interceptionContext.Result = newInsertCommand; // True means an interception successfully happened so there is no need to continue return(true); }
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 } }
protected override Expression VisitConstant(ConstantExpression node) { var expression = base.VisitConstant(node); var type = node.Type; if (IsNullableType(type)) { var genericArgs = type.GetGenericArguments(); if ((genericArgs != null) && (genericArgs.Length == 1)) { type = genericArgs[0]; } } if (type == typeof(byte[])) { MapExpressionToDbExpression(expression, DbExpression.FromBinary((byte[])node.Value)); } else if (type == typeof(bool)) { MapExpressionToDbExpression(expression, DbExpression.FromBoolean((bool?)node.Value)); } else if (type == typeof(byte)) { MapExpressionToDbExpression(expression, DbExpression.FromByte((byte?)node.Value)); } else if (type == typeof(DateTime)) { MapExpressionToDbExpression(expression, DbExpression.FromDateTime((DateTime?)node.Value)); } else if (type == typeof(DateTimeOffset)) { MapExpressionToDbExpression(expression, DbExpression.FromDateTimeOffset((DateTimeOffset?)node.Value)); } else if (type == typeof(decimal)) { MapExpressionToDbExpression(expression, DbExpression.FromDecimal((decimal?)node.Value)); } else if (type == typeof(double)) { MapExpressionToDbExpression(expression, DbExpression.FromDouble((double?)node.Value)); } else if (type == typeof(Guid)) { MapExpressionToDbExpression(expression, DbExpression.FromGuid((Guid?)node.Value)); } else if (type == typeof(Int16)) { MapExpressionToDbExpression(expression, DbExpression.FromInt16((Int16?)node.Value)); } else if (type == typeof(Int32)) { MapExpressionToDbExpression(expression, DbExpression.FromInt32((Int32?)node.Value)); } else if (type.IsEnum) { MapExpressionToDbExpression(expression, DbExpression.FromInt32((Int32)node.Value)); } else if (type == typeof(Int64)) { MapExpressionToDbExpression(expression, DbExpression.FromInt64((Int64?)node.Value)); } else if (type == typeof(float)) { MapExpressionToDbExpression(expression, DbExpression.FromSingle((float?)node.Value)); } else if (type == typeof(string)) { MapExpressionToDbExpression(expression, DbExpression.FromString((string)node.Value)); } else { throw new NotImplementedException(string.Format("Unhandled Type of {0} for Constant value {1} in LambdaToDbExpressionVisitor.VisitConstant", node.Type.Name, node.Value ?? "null")); } return(expression); }
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) { if (interceptionContext.OriginalResult.DataSpace != DataSpace.SSpace) { return; } var lastChange = DateTime.Now; var lastChangeBy = HttpContext.Current.User.Identity.Name; var insertCommand = interceptionContext.Result as DbInsertCommandTree; var updateCommand = interceptionContext.OriginalResult as DbUpdateCommandTree; if (insertCommand != null) { var setClauses = insertCommand.SetClauses .Select(clause => clause.UpdateIfMatch(LastChangeColumnName, DbExpression.FromDateTime(lastChange))) .Select(clause => clause.UpdateIfMatch(LastChangeByColumnName, DbExpression.FromString(lastChangeBy))) .ToList(); interceptionContext.Result = new DbInsertCommandTree(insertCommand.MetadataWorkspace, insertCommand.DataSpace, insertCommand.Target, setClauses.AsReadOnly(), insertCommand.Returning); } else if (updateCommand != null) { var setClauses = updateCommand.SetClauses .Select(clause => clause.UpdateIfMatch(LastChangeColumnName, DbExpression.FromDateTime(lastChange))) .Select(clause => clause.UpdateIfMatch(LastChangeByColumnName, DbExpression.FromString(lastChangeBy))) .ToList(); interceptionContext.Result = new DbUpdateCommandTree(updateCommand.MetadataWorkspace, updateCommand.DataSpace, updateCommand.Target, updateCommand.Predicate, setClauses.AsReadOnly(), null); } }
public virtual void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) { if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace) { // Check that there is an authenticated user in this context var identity = Thread.CurrentPrincipal.Identity; if (identity == null) { return; } //var userIdclaim = identity.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier); //if (userIdclaim == null) //{ // return; //} // In case of query command change the query by adding a filtering based on tenantId var queryCommand = interceptionContext.Result as DbQueryCommandTree; if (queryCommand != null) { var newQuery = queryCommand.Query.Accept(new FactoryQueryVisitor()); interceptionContext.Result = new DbQueryCommandTree( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery); return; } var insertCommand = interceptionContext.Result as DbInsertCommandTree; if (insertCommand != null) { var column = EdmHelper.GetFactoryColumnName(insertCommand.Target.VariableType.EdmType); if (!string.IsNullOrEmpty(column)) { // Create the variable reference in order to create the property var variableReference = DbExpressionBuilder.Variable(insertCommand.Target.VariableType, insertCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = DbExpressionBuilder.Property(variableReference, column); // Create the set clause, object representation of sql insert command var tenantSetClause = DbExpressionBuilder.SetClause(tenantProperty, DbExpression.FromString("1")); // Remove potential assignment of tenantId for extra safety var filteredSetClauses = insertCommand.SetClauses.Cast <DbSetClause>() .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column); // Construct the final clauses, object representation of sql insert command values var finalSetClauses = new ReadOnlyCollection <DbModificationClause> (new List <DbModificationClause>(filteredSetClauses) { tenantSetClause }); var newInsertCommand = new DbInsertCommandTree( insertCommand.MetadataWorkspace, insertCommand.DataSpace, insertCommand.Target, finalSetClauses, insertCommand.Returning); interceptionContext.Result = newInsertCommand; return; } } } }