Migrating to 5.11 - DynamicQueryEngine and CreateSelectDQ

Posts   
 
    
Marco R
User
Posts: 2
Joined: 11-Feb-2013
# Posted on: 03-Jun-2024 19:35:50   

I downloaded the trial version of 5.11 to evaluate the work required to upgrade an old 4.2 project and ran into a problem that I haven't been able to figure out. It's SQL Server using the SelfServicing model. We have a method that takes PredicateExpression, RelationCollection, GroupByCollection, etc and then modifies the resulting command text (INSERT INTO.. SELECT FROM instead of just a select) before executing with SqlCommand.

The old code looks like this:

Dim dqe As New DynamicQueryEngine Dim retQ As IRetrievalQuery = dqe.CreateSelectDQ(selectFields.GetAsEntityFieldCoreArray, selectPersists.ToArray, trans.ConnectionToUse, filter, 0, Nothing, relations, False, groupBy) Dim insertSQL As String = RewriteForInsertQuery(retQ, jobId)

I think I see how the call to CreateSelectDQ would have to change as the signature is different and now takes QueryParameters, but the first line won't compile because it can't resolve DynamicQueryEngine which used to be found in SD.LLBLGen.Pro.DQE.SqlServer. Is there a different way of doing this now or am I missing something obvious?

We're only doing this in one spot so I could rewrite it to not use LLBLGen for this but I'd rather not since the logic for building the relations and predicates is old, complex, and working (LOL)

Marco R
User
Posts: 2
Joined: 11-Feb-2013
# Posted on: 03-Jun-2024 21:09:58   

Nevermind! My reference to SD.LLBLGen.Pro.DQE.SqlServer was screwed up.

HernanBsAs
User
Posts: 2
Joined: 12-Feb-2025
# Posted on: 12-Feb-2025 19:30:32   

I have this code working in the dataaccessadapter in llbgen 2.5

    protected override IRetrievalQuery CreateSelectDQ(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfoObjects,
                                                 IPredicateExpression filter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk,
                                                 bool allowDuplicates, IGroupByCollection groupByClause, int pageNumber, int pageSize)
    {
        IRetrievalQuery query = base.CreateSelectDQ(fieldsToFetch, persistenceInfoObjects, filter, maxNumberOfItemsToReturn, sortClauses, relationsToWalk,
                                        allowDuplicates, groupByClause, pageNumber, pageSize);

        // this line of code needs to fbe removed as soon as Microsoft can fix sp_executesql.
        // fix the wild card search query performance issue in LLBL by declaring the parameter variables inside of query string.
        if (_useNewMethod)
        {
            query.Command.CommandText = RewriteQuery(query);
        }

        return query;
    }

Migrating the code to version 5.11 base.CreateSelectDQ is no longer available....

In the documentations appears

The signatures of DynamicQueryEngineBase.CreateSelectDQ() methods have been changed, some have been removed as part of a refactoring to pass QueryParameters to the engines instead of a series of separate arguments. Normally you won't run into this breaking change, but if you have your own DQE classes, you have to adjust CreatePagingSelectDQ to call CreateSelectDQImpl() instead and make sure the query is generated in an override of CreateSelectDQImpl() (or use the base implementation). Please consult the source code archive for the sources of the shipped DQE engines to see which methods are called where and which arguments to pass.

anny suggestion?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39825
Joined: 17-Aug-2003
# Posted on: 13-Feb-2025 08:15:50   

Please don't re-open old threads, but start a new one next time. Thanks!

I don't know what 'RewriteQuery(query)' does, so I can't advice what you should do. WHat does it do? (as I don't recall it was part of our codebase)

Frans Bouma | Lead developer LLBLGen Pro
HernanBsAs
User
Posts: 2
Joined: 12-Feb-2025
# Posted on: 13-Feb-2025 16:54:03   

Thanks a lot. To explain better the problem in the original version with llbgenPro 2.50 in the DataaccessAdapter this codes overrides CreateselectDQ adding a filter to the query by a field When we migrates to 5.11 the base member CreateSelectDQ gives an error

  **IRetrievalQuery query = base.CreateSelectDQ**

Any idea to replace this code in the new version...

The code that does,t work

*protected override IRetrievalQuery CreateSelectDQ(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfoObjects, IPredicateExpression filter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, bool allowDuplicates, IGroupByCollection groupByClause, int pageNumber, int pageSize) { IRetrievalQuery query = base.CreateSelectDQ(fieldsToFetch, persistenceInfoObjects, filter, maxNumberOfItemsToReturn, sortClauses, relationsToWalk, allowDuplicates, groupByClause, pageNumber, pageSize);

        // this line of code needs to fbe removed as soon as Microsoft can fix sp_executesql.
        // fix the wild card search query performance issue in LLBL by declaring the parameter variables inside of query string.
        if (_useNewMethod)
        {
            query.Command.CommandText = RewriteQuery(query);
        }

        return query;
    }

    private string RewriteQuery(IQuery selectQuery)
    {
        StringBuilder declare = new StringBuilder();
        StringBuilder set = new StringBuilder();
        foreach (SqlParameter param in selectQuery.Parameters)
        {
            declare.AppendLine(String.Format("declare {0}_param {1}", param.ParameterName, param.SqlDbType));

            // Character columns need the length attached. 
            if (param.SqlDbType.ToString().IndexOf("CHAR", StringComparison.CurrentCultureIgnoreCase) != -1)
            {
                declare.Append(String.Format("({0})", param.Size)); //Add character lengths.
                declare.AppendLine();
            }

            set.AppendLine(String.Format("set {0}_param = {0};", param.ParameterName));
        }
        return String.Format("{0}\r\n{1}\r\n{2}", declare, set, ReplaceVars(selectQuery.Command.CommandText));
    }

    private string ReplaceVars(string source)
    {
        Regex reg = new Regex(@"(@[\w|_]+)");
        return reg.Replace(source, "$1_param");
    }*
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39825
Joined: 17-Aug-2003
# Posted on: 14-Feb-2025 08:23:37   

I think your code is meant to prevent the issue with what's called 'parameter sniffing', a problem that plagued SQL Server in earlier versions where it made the wrong decision when compiling execution plans which resulted in very slow query performance. To mitigate that, you could define the parameters in-line and skip execute_sql, the stored procedure that actually executes the dynamic sql.

However I wouldn't worry about it nowadays. So if I were you, I'd just skip this code as it's unlikely needed today

Frans Bouma | Lead developer LLBLGen Pro