コード例 #1
0
        public static Expression Optimize(Expression expression, Type typeForEnums, bool simplerPartialVal = true)
        {
            expression = ObjectOperandComparisonExpander.Expand(expression);
            expression = EnumTypeNormalizer.Normalize(expression, typeForEnums);
            expression = GroupByCollator.Collate(expression);
            expression = AggregateSubqueryRewriter.Rewrite(expression);
            expression = UnusedColumnRemover.Remove(expression);
            expression = RedundantColumnRemover.Remove(expression);
            expression = RedundantSubqueryRemover.Remove(expression);
            expression = FunctionCoalescer.Coalesce(expression);
            expression = ExistsSubqueryOptimizer.Optimize(expression);
            expression = RedundantBinaryExpressionsRemover.Remove(expression);

            if (simplerPartialVal)
            {
                expression = Evaluator.PartialEval(expression, c => c.NodeType != (ExpressionType)SqlExpressionType.ConstantPlaceholder && Evaluator.CanBeEvaluatedLocally(c));
            }
            else
            {
                expression = Evaluator.PartialEval(expression);
            }

            expression = RedundantFunctionCallRemover.Remove(expression);
            expression = ConditionalEliminator.Eliminate(expression);
            expression = SqlExpressionCollectionOperationsExpander.Expand(expression);
            expression = SumAggregatesDefaultValueCoalescer.Coalesce(expression);
            expression = OrderByRewriter.Rewrite(expression);

            return(expression);
        }
コード例 #2
0
        public static void DeleteWhere <T>(this DataAccessObjectsQueryable <T> queryable, Expression <Func <T, bool> > condition)
            where T : DataAccessObject
        {
            queryable.DataAccessModel.Flush();

            var transactionContext = queryable.DataAccessModel.AmbientTransactionManager.GetCurrentContext(true);

            using (var acquisition = transactionContext.AcquirePersistenceTransactionContext(queryable.DataAccessModel.GetCurrentSqlDatabaseContext()))
            {
                var expression = (Expression)Expression.Call(null, MethodCache <T> .DeleteMethod, Expression.Constant(queryable, typeof(DataAccessObjectsQueryable <T>)), condition);

                expression = Evaluator.PartialEval(expression);
                expression = QueryBinder.Bind(queryable.DataAccessModel, expression, queryable.ElementType, queryable.ExtraCondition);
                expression = ObjectOperandComparisonExpander.Expand(expression);
                expression = SqlQueryProvider.Optimize(expression, transactionContext.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums());

                acquisition.SqlDatabaseCommandsContext.Delete((SqlDeleteExpression)expression);
            }
        }
コード例 #3
0
        public override void Delete(Type type, IEnumerable <DataAccessObject> dataAccessObjects)
        {
            var typeDescriptor = this.DataAccessModel.GetTypeDescriptor(type);
            var parameter      = Expression.Parameter(typeDescriptor.Type, "value");

            Expression body = null;

            foreach (var dataAccessObject in dataAccessObjects)
            {
                var currentExpression = Expression.Equal(parameter, Expression.Constant(dataAccessObject));

                if (body == null)
                {
                    body = currentExpression;
                }
                else
                {
                    body = Expression.OrElse(body, currentExpression);
                }
            }

            if (body == null)
            {
                return;
            }

            var condition  = Expression.Lambda(body, parameter);
            var expression = (Expression)Expression.Call(null, GetDeleteMethod(typeDescriptor.Type), Expression.Constant(null, typeDescriptor.Type), condition);

            expression = Evaluator.PartialEval(expression);
            expression = QueryBinder.Bind(this.DataAccessModel, expression, null, null);
            expression = ObjectOperandComparisonExpander.Expand(expression);
            expression = SqlQueryProvider.Optimize(expression, this.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums());

            Delete((SqlDeleteExpression)expression);
        }
コード例 #4
0
ファイル: ProjectionBuilder.cs プロジェクト: smadep/Shaolinq
        protected override Expression VisitMemberInit(MemberInitExpression expression)
        {
            var previousCurrentNewExpressionType = currentNewExpressionType;

            currentNewExpressionType = expression.NewExpression.Type;

            Expression nullCheck = null;

            foreach (var value in ObjectOperandComparisonExpander
                     .GetPrimaryKeyElementalExpressions(expression))
            {
                Expression current;

                if (value.NodeType == (ExpressionType)SqlExpressionType.Column)
                {
                    current = this.ConvertColumnToIsNull((SqlColumnExpression)value);
                }
                else
                {
                    var visited = this.Visit(value);

                    if (visited.Type.IsClass || visited.Type.IsNullableType())
                    {
                        current = Expression.Equal(Expression.Convert(visited, visited.Type), Expression.Constant(null, visited.Type));
                    }
                    else
                    {
                        current = Expression.Equal(Expression.Convert(visited, visited.Type.MakeNullable()), Expression.Constant(null, visited.Type));
                    }
                }

                if (nullCheck == null)
                {
                    nullCheck = current;
                }
                else
                {
                    nullCheck = Expression.Or(nullCheck, current);
                }
            }

            var retval = base.VisitMemberInit(expression);

            currentNewExpressionType = previousCurrentNewExpressionType;

            if (typeof(DataAccessObject).IsAssignableFrom(retval.Type))
            {
                var submitToCacheMethod        = typeof(IDataAccessObjectInternal).GetMethod("SubmitToCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                var resetModifiedMethod        = typeof(IDataAccessObjectInternal).GetMethod("ResetModified", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                var finishedInitializingMethod = typeof(IDataAccessObjectInternal).GetMethod("FinishedInitializing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

                retval = Expression.Convert(Expression.Call(Expression.Call(Expression.Call(Expression.Convert(retval, typeof(IDataAccessObjectInternal)), finishedInitializingMethod), resetModifiedMethod), submitToCacheMethod), retval.Type);
            }

            if (nullCheck != null)
            {
                return(Expression.Condition(nullCheck, Expression.Constant(null, retval.Type), retval));
            }
            else
            {
                return(retval);
            }
        }
コード例 #5
0
        protected virtual IDbCommand BuildUpdateCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject)
        {
            IDbCommand      command;
            SqlCommandValue sqlCommandValue;
            var             updatedProperties = dataAccessObject.GetAdvanced().GetChangedPropertiesFlattened();

            if (updatedProperties.Count == 0)
            {
                return(null);
            }

            var primaryKeys = dataAccessObject.GetAdvanced().GetPrimaryKeysForUpdateFlattened();
            var commandKey  = new SqlCommandKey(dataAccessObject.GetType(), updatedProperties);

            if (this.TryGetUpdateCommand(commandKey, out sqlCommandValue))
            {
                command             = CreateCommand();
                command.CommandText = sqlCommandValue.commandText;
                FillParameters(command, updatedProperties, primaryKeys);

                return(command);
            }

            var assignments = updatedProperties.Select(c => (Expression) new SqlAssignExpression(new SqlColumnExpression(c.PropertyType, null, c.PersistedName), Expression.Constant(c.Value))).ToReadOnlyList();

            Expression where = null;

            var i = 0;

            Debug.Assert(primaryKeys.Length > 0);

            foreach (var primaryKey in primaryKeys)
            {
                var currentExpression = Expression.Equal(new SqlColumnExpression(primaryKey.PropertyType, null, primaryKey.PersistedName), Expression.Constant(primaryKey.Value));

                if (where == null)
                {
                    where = currentExpression;
                }
                else
                {
                    where = Expression.And(where, currentExpression);
                }

                i++;
            }

            var expression = new SqlUpdateExpression(new SqlTableExpression(typeDescriptor.PersistedName), assignments, where);

            expression = (SqlUpdateExpression)ObjectOperandComparisonExpander.Expand(expression);

            var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression, SqlQueryFormatterOptions.Default & ~SqlQueryFormatterOptions.OptimiseOutConstantNulls);

            command = CreateCommand();

            command.CommandText = result.CommandText;
            CacheUpdateCommand(commandKey, new SqlCommandValue()
            {
                commandText = command.CommandText
            });
            FillParameters(command, updatedProperties, primaryKeys);

            return(command);
        }