private static string BuildSqlForDateTimeOffset(DateTimeOffset dateTimeOffset, SqlVersion sqlVersion)
        {
            var builder = new StringBuilder();

            var sqlGenerator = new SqlGenerator(sqlVersion);

            var functionExpression = EdmFunctions.CreateDateTimeOffset(
                DbExpression.FromInt32(dateTimeOffset.Year),
                DbExpression.FromInt32(dateTimeOffset.Month),
                DbExpression.FromInt32(dateTimeOffset.Day),
                DbExpression.FromInt32(dateTimeOffset.Hour),
                DbExpression.FromInt32(dateTimeOffset.Minute),
                DbExpression.FromInt32(dateTimeOffset.Second),
                DbExpression.FromInt32(Convert.ToInt32(dateTimeOffset.Offset.TotalMinutes)));

            var sqlFragment = SqlFunctionCallHandler.GenerateFunctionCallSql(
                sqlGenerator, functionExpression);

            using (var sqlWriter = new SqlWriter(builder))
            {
                sqlFragment.WriteSql(sqlWriter, sqlGenerator);
            }

            return(builder.ToString());
        }
        public override DbExpression Visit(DbScanExpression expression)
        {
            //Check if POCO has system Status flag
            if (expression.Target.ElementType.Members.All(x => x.Name != "SystemStatus"))
            {
                return(base.Visit(expression));
            }

            //**** Copied this from the EF team: https://github.com/rowanmiller/Demo-TechEd2014 ****

            // Just because the entity has the soft delete annotation doesn't mean that
            // this particular table has the column. This occurs in situation like TPT
            // inheritance mapping and entity splitting where one type maps to multiple
            // tables.
            // We only apply the filter if the column is actually present in this table.
            // If not, then the query is going to be joining to the table that does have
            // the column anyway, so the filter will still be applied.
            var table = (EntityType)expression.Target.ElementType;

            if (table.Properties.Any(p => p.Name == "Status"))
            {
                var binding = expression.Bind();
                return
                    (binding.Filter(
                         binding.VariableType.Variable(binding.VariableName)
                         .Property("Status")
                         .NotEqual(DbExpression.FromInt32((int)SystemStatus.Deleted))));
            }

            return(base.Visit(expression));
        }
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
            {
                var queryCommand = interceptionContext.Result as DbQueryCommandTree;
                if (queryCommand != null)
                {
                    var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
                    interceptionContext.Result = new DbQueryCommandTree(
                        queryCommand.MetadataWorkspace,
                        queryCommand.DataSpace,
                        newQuery);
                }

                var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
                if (deleteCommand != null)
                {
                    //Check if POCO has system Status flag
                    if (
                        ((EntityType)deleteCommand.Target.VariableType.EdmType).DeclaredMembers.All(
                            x => x.Name != "SystemStatus"))
                    {
                        return;
                    }

                    // Just because the entity has the soft delete annotation doesn't mean that
                    // this particular table has the column. This occurs in situation like TPT
                    // inheritance mapping and entity splitting where one type maps to multiple
                    // tables.
                    // If the table doesn't have the column we just want to leave the row unchanged
                    // since it will be joined to the table that does have the column during query.
                    // We can't no-op, so we just generate an UPDATE command that doesn't set anything.
                    var setClauses = new List <DbModificationClause>();
                    var table      = (EntityType)deleteCommand.Target.VariableType.EdmType;
                    if (table.Properties.Any(p => p.Name == "SystemStatus"))
                    {
                        setClauses.Add(DbExpressionBuilder.SetClause(
                                           deleteCommand.Target.VariableType.Variable(deleteCommand.Target.VariableName)
                                           .Property("SystemStatus"),
                                           DbExpression.FromInt32((int)SystemStatus.Deleted)));
                    }

                    var update = new DbUpdateCommandTree(
                        deleteCommand.MetadataWorkspace,
                        deleteCommand.DataSpace,
                        deleteCommand.Target,
                        deleteCommand.Predicate,
                        setClauses.AsReadOnly(),
                        null);

                    interceptionContext.Result = update;
                }
            }
        }
        /// <summary>
        /// In case of an insert command we always assign the correct value to the tenantId
        /// </summary>
        private static bool InterceptInsertCommand(DbCommandTreeInterceptionContext interceptionContext, int userId)
        {
            var shoolcontextList = interceptionContext.DbContexts.OfType <SchoolContext>();

            if (shoolcontextList.Any(x => x.IsSeeding))
            {
                return(true);
            }

            var insertCommand = interceptionContext.Result as DbInsertCommandTree;

            if (insertCommand != null)
            {
                var column = TenantAwareAttribute.GetTenantColumnName(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.FromInt32(userId));

                    // 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);
                }
            }
            return(false);
        }
Exemple #5
0
    public override DbExpression Visit(DbScanExpression expression)
    {
        if (this.FilterValue > 0)
        {
            // Get the current expression
            var dbExpression = base.Visit(expression);
            var binding      = expression.Bind();
            return(binding.Filter(
                       binding.VariableType
                       .Variable(binding.VariableName)
                       .Property("FilterFieldName")
                       .Equal(DbExpression.FromInt32(this.FilterValue))));
        }

        return(base.Visit(expression));
    }
        public override DbExpression Visit(DbScanExpression expression)
        {
            var column = EdmHelper.GetFactoryColumnName(expression.Target.ElementType);

            if (!string.IsNullOrEmpty(column))
            {
                // Get the current expression
                var dbExpression = base.Visit(expression);
                // Get the current expression binding
                var currentExpressionBinding = DbExpressionBuilder.Bind(dbExpression);

                //FactoryId = @Paramname_1
                // Create the variable reference in order to create the property
                var variableReferenceLeftSide = DbExpressionBuilder.Variable(currentExpressionBinding.VariableType,
                                                                             currentExpressionBinding.VariableName);
                // Create the property based on the variable in order to apply the equality
                var tenantPropertyLeftSide = DbExpressionBuilder.Property(variableReferenceLeftSide, column);
                // Create the parameter which is an object representation of a sql parameter.
                // We have to create a parameter and not perform a direct comparison with Equal function for example
                // as this logic is cached per query and called only once
                var tenantParameterLeftSide = DbExpressionBuilder.Parameter(tenantPropertyLeftSide.Property.TypeUsage,
                                                                            FactoryConstants.FactoryIdFilterParameterName);
                // Apply the equality between property and parameter.
                var filterExpressionLeftSide = DbExpressionBuilder.Equal(tenantPropertyLeftSide, tenantParameterLeftSide);

                //1 = @Paramname_2
                // Create the variable reference in order to create the property
                var variableReferenceRightSide = DbExpressionBuilder.Variable(currentExpressionBinding.VariableType,
                                                                              currentExpressionBinding.VariableName);
                // Create the property based on the variable in order to apply the equality
                var tenantPropertyRightSide = DbExpression.FromInt32(1);
                // Create the parameter which is an object representation of a sql parameter.
                // We have to create a parameter and not perform a direct comparison with Equal function for example
                // as this logic is cached per query and called only once
                var tenantParameterRightSide = DbExpressionBuilder.Parameter(TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                                                                             FactoryConstants.FactoryOverrideFilterParameterName);
                // Apply the equality between property and parameter.
                var filterExpressionRightSide = DbExpressionBuilder.Equal(tenantPropertyRightSide, tenantParameterRightSide);
                DbExpressionBuilder.
                var filterExpression = DbExpressionBuilder.Or(filterExpressionLeftSide, filterExpressionRightSide);

                // Apply the filtering to the initial query
                return(DbExpressionBuilder.Filter(currentExpressionBinding, filterExpression));
            }

            return(base.Visit(expression));
        }
Exemple #7
0
            public override DbExpression Visit(DbScanExpression expression)
            {
                var table = (EntityType)expression.Target.ElementType;

                if (table.Properties.All(p => p.Name != IsDeletedColumnName))
                {
                    return(base.Visit(expression));
                }

                var binding = expression.Bind();

                return(binding.Filter(
                           binding.VariableType
                           .Variable(binding.VariableName)
                           .Property(IsDeletedColumnName)
                           .NotEqual(DbExpression.FromInt32(1))));
            }
Exemple #8
0
        private static DbCommandTree HandleDeleteCommand(DbDeleteCommandTree deleteCommand)
        {
            var setClauses = new List <DbModificationClause>();
            var table      = (EntityType)deleteCommand.Target.VariableType.EdmType;

            if (table.Properties.All(p => p.Name != IsDeletedColumnName))
            {
                return(deleteCommand);
            }

            setClauses.Add(DbExpressionBuilder.SetClause(
                               deleteCommand.Target.VariableType.Variable(deleteCommand.Target.VariableName).Property(IsDeletedColumnName),
                               DbExpression.FromInt32(1)));

            return(new DbUpdateCommandTree(
                       deleteCommand.MetadataWorkspace,
                       deleteCommand.DataSpace,
                       deleteCommand.Target,
                       deleteCommand.Predicate,
                       setClauses.AsReadOnly(), null));
        }
        /// <summary>
        /// In case of a delete command we always filter based on the userId
        /// </summary>
        static void InterceptDeleteCommand(DbCommandTreeInterceptionContext interceptionContext)
        {
            var deleteCommand = interceptionContext.Result as DbDeleteCommandTree;

            if (deleteCommand != null)
            {
                var column = UserAwareAttribute.GetUserColumnName(deleteCommand.Target.VariableType.EdmType);
                if (!string.IsNullOrEmpty(column))
                {
                    // Get the userId (throw an exception if there is none)
                    var userId = GetCurrentUserId();

                    // Create the variable reference in order to create the property
                    var variableReference = DbExpressionBuilder.Variable(deleteCommand.Target.VariableType,
                                                                         deleteCommand.Target.VariableName);
                    // Create the property to which will assign the correct value
                    var userProperty         = DbExpressionBuilder.Property(variableReference, column);
                    var userIdWherePredicate = DbExpressionBuilder.Equal(userProperty, DbExpression.FromInt32(userId));

                    // The initial predicate is the sql where statement
                    var initialPredicate = deleteCommand.Predicate;
                    // Add to the initial statement the userId statement which translates in sql AND userId = 'value'
                    var finalPredicate = initialPredicate.And(userIdWherePredicate);

                    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 userId
        /// </summary>
        static bool InterceptUpdate(DbCommandTreeInterceptionContext interceptionContext)
        {
            var updateCommand = interceptionContext.Result as DbUpdateCommandTree;

            if (updateCommand != null)
            {
                var column = UserAwareAttribute.GetUserColumnName(updateCommand.Target.VariableType.EdmType);
                if (!string.IsNullOrEmpty(column))
                {
                    // Get the userId (throw an exception if there is none)
                    var userId = GetCurrentUserId();

                    // Create the variable reference in order to create the property
                    var variableReference = DbExpressionBuilder.Variable(updateCommand.Target.VariableType,
                                                                         updateCommand.Target.VariableName);
                    // Create the property to which will assign the correct value
                    var userProperty = DbExpressionBuilder.Property(variableReference, column);
                    // Create the userId where predicate, object representation of sql where userId = value statement
                    var userIdWherePredicate = DbExpressionBuilder.Equal(userProperty, DbExpression.FromInt32(userId));

                    // Remove potential assignment of userId 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 userId statement which translates in sql AND UserId = 'value'
                    var finalPredicate = initialPredicate.And(userIdWherePredicate);

                    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);
                }
            }
            return(false);
        }
        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);
        }