예제 #1
0
        public static string GenerateSQL(ICriteria criteria)
        {
            var criteriaImpl = (CriteriaImpl)criteria;
            ISessionImplementor        session = criteriaImpl.Session;
            ISessionFactoryImplementor factory = session.Factory;

            var translator =
                new CriteriaQueryTranslator(
                    factory,
                    criteriaImpl,
                    criteriaImpl.EntityOrClassName,
                    CriteriaQueryTranslator.RootSqlAlias);

            String[] implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName);

            var walker = new CriteriaJoinWalker(
                (IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]),
                translator,
                factory,
                criteriaImpl,
                criteriaImpl.EntityOrClassName,
                session.EnabledFilters);

            return(walker.SqlString.ToString());
        }
예제 #2
0
        public void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery)
        {
            if (innerQuery == null)
            {
                ISessionFactoryImplementor factory = criteriaQuery.Factory;

                innerQuery =
                    new CriteriaQueryTranslator(
                        factory,
                        criteriaImpl,                         //implicit polymorphism not supported (would need a union)
                        criteriaImpl.EntityOrClassName,
                        criteriaQuery.GenerateSQLAlias(),
                        criteriaQuery);

                if (innerQuery.HasProjection)
                {
                    parameters = innerQuery.GetQueryParameters();
                    types      = innerQuery.ProjectedTypes;
                }
                else
                {
                    types = null;
                }
            }
        }
 protected void CreateObjects(System.Type rootClass, ISession session)
 {
     criteria      = (CriteriaImpl)session.CreateCriteria(rootClass);
     criteriaQuery = new CriteriaQueryTranslator(
         (ISessionFactoryImplementor)factory,
         criteria, criteria.EntityOrClassName, SqlAlias);
 }
예제 #4
0
        public void EqOrNullTest()
        {
            using (ISession session = OpenSession())
            {
                var criteria      = (CriteriaImpl)session.CreateCriteria(typeof(Simple));
                var criteriaQuery = new CriteriaQueryTranslator(sessions, criteria, criteria.EntityOrClassName, "sql_alias");

                ICriterion exp       = Criterion.EqOrNull("Name", "foo");
                SqlString  sqlString = exp.ToSqlString(criteria, criteriaQuery, new CollectionHelper.EmptyMapClass <string, IFilter>());

                string expectedSql = "sql_alias.Name = ?";

                Assert.AreEqual(expectedSql, sqlString.ToString());
                Assert.AreEqual(1, sqlString.GetParameterCount());

                exp       = Criterion.EqOrNull("Name", null);
                sqlString = exp.ToSqlString(criteria, criteriaQuery, new CollectionHelper.EmptyMapClass <string, IFilter>());

                expectedSql = "sql_alias.Name is null";

                Assert.AreEqual(expectedSql, sqlString.ToString());
                Assert.AreEqual(0, sqlString.GetParameterCount());

                // Check that the result is the same than using official Restriction
                ICriterion orExpExpected = Restrictions.Or(Restrictions.IsNull("Name"), Restrictions.Eq("Name", "foo"));
                ICriterion orExpActual   = Restrictions.Or(Criterion.EqOrNull("Name", null), Criterion.EqOrNull("Name", "foo"));

                SqlString sqlStringExpected = orExpExpected.ToSqlString(criteria, criteriaQuery,
                                                                        new CollectionHelper.EmptyMapClass <string, IFilter>());
                SqlString sqlStringActual = orExpActual.ToSqlString(criteria, criteriaQuery,
                                                                    new CollectionHelper.EmptyMapClass <string, IFilter>());
                Assert.AreEqual(sqlStringExpected.ToString(), sqlStringActual.ToString());
            }
        }
예제 #5
0
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            ISessionFactoryImplementor factory = criteriaQuery.Factory;

            var innerQuery = new CriteriaQueryTranslator(
                factory,
                criteriaImpl,                 //implicit polymorphism not supported (would need a union)
                criteriaImpl.EntityOrClassName,
                criteriaQuery.GenerateSQLAlias(),
                criteriaQuery);

            types = innerQuery.HasProjection ? innerQuery.ProjectedTypes : null;

            if (innerQuery.HasProjection == false)
            {
                throw new QueryException("Cannot use subqueries on a criteria without a projection.");
            }

            IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

            //patch to generate joins on subqueries
            //stolen from CriteriaLoader
            CriteriaJoinWalker walker =
                new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

            parameters = innerQuery.GetQueryParameters();             // parameters can be inferred only after initialize the walker

            SqlString sql = walker.SqlString;

            if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
            {
                int?      offset          = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
                int?      limit           = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
                Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
                Parameter limitParameter  = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
                sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
            }

            SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));

            if (op != null)
            {
                buf.Add(" ").Add(op).Add(" ");
            }

            if (quantifier != null && prefixOp)
            {
                buf.Add(quantifier).Add(" ");
            }

            buf.Add("(").Add(sql).Add(")");

            if (quantifier != null && prefixOp == false)
            {
                buf.Add(" ").Add(quantifier);
            }

            return(buf.ToSqlString());
        }
예제 #6
0
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            InitializeInnerQueryAndParameters(criteriaQuery);

            if (innerQuery.HasProjection == false)
            {
                throw new QueryException("Cannot use subqueries on a criteria without a projection.");
            }

            ISessionFactoryImplementor factory = criteriaQuery.Factory;

            IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName);

            //patch to generate joins on subqueries
            //stolen from CriteriaLoader
            CriteriaJoinWalker walker =
                new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters);

            parameters = innerQuery.GetQueryParameters();             // parameters can be inferred only after initialize the walker

            SqlString sql = walker.SqlString;

            if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue)
            {
                int?      offset          = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect);
                int?      limit           = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect);
                Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null;
                Parameter limitParameter  = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null;
                sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter);
            }

            // during CriteriaImpl.Clone we are doing a shallow copy of each criterion.
            // this is not a problem for common criterion but not for SubqueryExpression because here we are holding the state of inner CriteriaTraslator (ICriteriaQuery).
            // After execution (ToSqlString) we have to clean the internal state because the next execution may be performed in a different tree reusing the same istance of SubqueryExpression.
            innerQuery = null;

            SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery));

            if (op != null)
            {
                buf.Add(" ").Add(op).Add(" ");
            }

            if (quantifier != null && prefixOp)
            {
                buf.Add(quantifier).Add(" ");
            }

            buf.Add("(").Add(sql).Add(")");

            if (quantifier != null && prefixOp == false)
            {
                buf.Add(" ").Add(quantifier);
            }

            return(buf.ToSqlString());
        }
예제 #7
0
 private void CombineCriteriaQueries()
 {
     foreach (CriteriaLoader loader in loaders)
     {
         CriteriaQueryTranslator translator = loader.Translator;
         translators.Add(translator);
         QueryParameters queryParameters = translator.GetQueryParameters();
         parameters.Add(queryParameters);
         ISqlCommand singleCommand = loader.CreateSqlCommand(queryParameters, session);
         resultSetsCommand.Append(singleCommand);
     }
 }
예제 #8
0
 private void CombineCriteriaQueries()
 {
     foreach (CriteriaLoader loader in loaders)
     {
         CriteriaQueryTranslator translator = loader.Translator;
         translators.Add(translator);
         QueryParameters queryParameters = translator.GetQueryParameters();
         parameters.Add(queryParameters);
         SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters, resultSetsCommand.ParametersCount);
         resultSetsCommand.Append(commandInfo);
     }
 }
예제 #9
0
 private void CombineCriteriaQueries()
 {
     foreach (CriteriaLoader loader in loaders)
     {
         CriteriaQueryTranslator translator = loader.Translator;
         translators.Add(translator);
         QueryParameters queryParameters = translator.GetQueryParameters();
         parameters.Add(queryParameters);
         SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters);
         sqlString = sqlString.Append(commandInfo.Text)
                     .Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator)
                     .Append(Environment.NewLine);
         types.AddRange(commandInfo.ParameterTypes);
     }
 }
        public void StartsWithTest()
        {
            using (ISession session = OpenSession())
            {
                var criteria      = (CriteriaImpl)session.CreateCriteria(typeof(Simple));
                var criteriaQuery = new CriteriaQueryTranslator(sessions, criteria, criteria.EntityOrClassName, "sql_alias");

                ICriterion exp       = Criterion.StartsWith("Number", "2");
                SqlString  sqlString = exp.ToSqlString(criteria, criteriaQuery, new CollectionHelper.EmptyMapClass <string, IFilter>());

                string expectedSql = "sql_alias.Number like ?";

                Assert.AreEqual(expectedSql, sqlString.ToString());
                Assert.AreEqual(1, sqlString.GetParameterCount());
            }
        }
예제 #11
0
        protected void InitProjection(CriteriaQueryTranslator translator,
                                      IDictionary <string, IFilter> enabledFilters, LockMode lockMode)
        {
            // the order of the calls here is important, as the join clauses can contain parameter bindings
            SqlString projectionString = translator.GetSelect(enabledFilters);

            WalkEntityTree(persister, Alias);
            SqlString whereString   = translator.GetWhereCondition(enabledFilters);
            SqlString orderByString = translator.GetOrderBy();
            SqlString groupByString = translator.GetGroupBy();
            SqlString havingString  = translator.GetHavingCondition(enabledFilters);

            Persisters = new ILoadable[0];
            InitStatementString(projectionString, whereString, orderByString, groupByString.ToString(),
                                havingString, lockMode);
        }
예제 #12
0
        public FilteredQueryOver(ISession session)
        {
            session.ThrowIfNull("session");

            Session = session;
            var metadata = Session.SessionFactory.GetClassMetadata(typeof(TEntity));

            entityPersister     = metadata as SingleTableEntityPersister;
            naturalIdProperties = metadata.NaturalIdentifierProperties.Select(x => metadata.PropertyNames[x]).ToList();
            var criteria         = (CriteriaImpl)Session.CreateCriteria <TEntity>();
            var selectTranslator = new CriteriaQueryTranslator(Session.GetSessionImplementation().Factory, criteria,
                                                               criteria.EntityOrClassName, "_Data");

            foreach (var property in metadata.PropertyNames)
            {
                selectedPropertyToColumnAliasMap[property] =
                    selectTranslator.GetColumnsUsingProjection(criteria, property).ToList();
            }
            baseSelectSql = criteria.GenerateSql(translator: selectTranslator);
        }
예제 #13
0
        public static SqlString GenerateSql(
            this ICriteria criteria,
            ISession session = null,
            CriteriaQueryTranslator translator = null)
        {
            criteria.ThrowIfNull("this");

            var criteriaImpl = (CriteriaImpl)criteria;

            var sessionImplementor = criteriaImpl.Session;

            if (sessionImplementor == null && session != null)
            {
                sessionImplementor = session.GetSessionImplementation();
            }
            if (sessionImplementor == null)
            {
                throw new InvalidOperationException("Criteria is detached from session and no session was specified");
            }
            var sessionImpl = (SessionImpl)sessionImplementor;

            var factory      = (SessionFactoryImpl)sessionImpl.SessionFactory;
            var implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName);

            if (translator == null)
            {
                translator = new CriteriaQueryTranslator(
                    factory,
                    criteriaImpl,
                    criteriaImpl.EntityOrClassName,
                    CriteriaQueryTranslator.RootSqlAlias);
            }

            CriteriaJoinWalker walker = new CriteriaJoinWalker((IOuterJoinLoadable)factory.GetEntityPersister(implementors[0]),
                                                               translator, factory, criteriaImpl, criteriaImpl.EntityOrClassName, sessionImpl.EnabledFilters);

            return(walker.SqlString);
        }
예제 #14
0
        private ISQLQuery CompileQuery()
        {
            var subcriteria    = (CriteriaImpl)Session.CreateCriteria <TEntity>();;
            var projectionList = Projections.ProjectionList();

            foreach (var projection in projections)
            {
                projectionList.Add(projection.Value, projection.Key);
            }
            subcriteria.SetProjection(projectionList);
            foreach (var criterion in criterions)
            {
                subcriteria.Add(criterion.Value);
            }

            var subqueryTranslator = new CriteriaQueryTranslator(Session.GetSessionImplementation().Factory, subcriteria,
                                                                 subcriteria.EntityOrClassName, "_InnerFilter");

            var filterPropertyToColumnAliasMap = new Dictionary <string, List <string> >();

            foreach (var projection in projections)
            {
                filterPropertyToColumnAliasMap[projection.Key] =
                    subqueryTranslator.GetColumnAliasesUsingProjection(subcriteria, projection.Key).ToList();
            }

            var joinOnMap = new Dictionary <string, string>();

            foreach (var projection in projections)
            {
                var selectColumns = selectedPropertyToColumnAliasMap[projection.Key];
                var filterColumns = filterPropertyToColumnAliasMap[projection.Key];
                var columnsCount  = Math.Min(selectColumns.Count, filterColumns.Count);
                for (int columnIndex = 0; columnIndex < columnsCount; columnIndex++)
                {
                    joinOnMap[selectColumns[columnIndex]] = filterColumns[columnIndex];
                }
            }
            var subcriteriaSqlString = subcriteria.GenerateSql(translator: subqueryTranslator);

            var queryBuilder = new StringBuilder();

            //TODO: Why this does not work: NHibernate tries to resolve "{PropertyName}", but result contains some odd mangled name
            //queryBuilder.AppendLine(baseSelectSql);
            queryBuilder.AppendLine("SELECT _Data.* FROM " + entityPersister.TableName + " AS _Data");
            queryBuilder.AppendLine("INNER JOIN (");
            queryBuilder.Append("\t");
            queryBuilder.AppendLine(subcriteriaSqlString.ToString());
            queryBuilder.AppendLine(") AS _Filter");
            queryBuilder.AppendLine("ON");
            queryBuilder.AppendLine(string.Join(" AND \n",
                                                joinOnMap.Select(x => string.Format("\t{0} = _Filter.{1}", x.Key, x.Value))));

            var sqlQuery = Session.CreateSQLQuery(queryBuilder.ToString());

            var parameterEnumerator = subqueryTranslator.CollectedParameters.GetEnumerator();
            var parameterSpecificationEnumerator = subqueryTranslator.CollectedParameterSpecifications.GetEnumerator();

            for (var parameterIndex = 0; parameterIndex < subcriteriaSqlString.GetParameterCount(); parameterIndex++)
            {
                parameterEnumerator.MoveNext();
                parameterSpecificationEnumerator.MoveNext();

                var parameter = parameterEnumerator.Current;
                var parameterSpecification = parameterSpecificationEnumerator.Current;
                sqlQuery.SetParameter(parameterIndex, parameter.Value, parameter.Type);
            }

            return(sqlQuery);
        }