NullReferenceException - SortExpression ToQueryText

Posts   
 
    
sacochra
User
Posts: 2
Joined: 05-Dec-2014
# Posted on: 05-Dec-2014 20:17:56   

Oracle.ManagedDataAccess. v.4.2 (4.2.14.1017)

Hello, we are seeing intermittent null reference exceptions when supplying a SortExpression. I had downloaded the source code and looked into the ToQueryText method. What we saw was that the fieldname was generated properly by the DatabaseSpecificCreator.CreateFieldName call , when the DatabaseSpecificCreator called ConvertSortOperator, the DatabaseSpecificCreator throws a NullReferenceException.


System.NullReferenceException: Object reference not set to an instance of an object.
   at SD.LLBLGen.Pro.ORMSupportClasses.SortExpression.ToQueryText(Boolean aliasesForExpressionsAggregates)
   at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.AppendOrderByClause(ISortExpression sortClauses, QueryFragments destination, IQuery query)
   at SD.LLBLGen.Pro.DQE.Oracle.DynamicQueryEngine.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IRetrievalQuery query, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Boolean relationsSpecified, Boolean sortClausesSpecified)
   at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, DbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause)
   at SD.LLBLGen.Pro.DQE.Oracle.DynamicQueryEngine.CreatePagingSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, DbConnection connectionToUse, IPredicate selectFilter, Int32 rowsToSkip, Int32 rowsToTake, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, DbConnection connectionToUse, IPredicate selectFilter, Int32 rowsToSkip, Int32 rowsToTake, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.CreateSelectDQ(QueryParameters parameters)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollectionInternal(QueryParameters parameters)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(QueryParameters parameters)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>n__FabricatedMethodd8(QueryParameters)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>c__DisplayClassd6.<FetchEntityCollection>b__d5()
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteWithActiveRecoveryStrategy(Action toExecute)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(QueryParameters parameters)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses)

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 06-Dec-2014 07:43:18   

Ther SortExpression by itself doesn't know anything about the real field names in the database. The persistence information needs to be inserted in order to SortExpression to emit correct SQL code.

Do this:

In a DataAccessAdapter partial class write this:

public partial class DataAccessAdapter
{
    public string GetQuery(SortExpression sorter)
    {
        InsertPersistenceInfoObjects(sorter);
        sorter.DatabaseSpecificCreator = this.GetDbSpecificCreatorInstance();
        return sorter.ToQueryText();
    }
}

Then, at your code:

using (var adapter = new DataAccessAdapter())
{
    var queryText = adapter.GetQuery(sorter);
}
David Elizondo | LLBLGen Support Team
sacochra
User
Posts: 2
Joined: 05-Dec-2014
# Posted on: 08-Dec-2014 18:18:49   

Thanks for responding, but I think I didn't explain the problem well.

Here is the SortExpression.cs code for the ToQueryText method.


 public virtual string ToQueryText(bool aliasesForExpressionsAggregates)
    {
      if (this._databaseSpecificCreator == null)
        throw new ApplicationException("DatabaseSpecificCreator object not set. Cannot create query part.");
      this._parameters = new List<DbParameter>();
      HashSet<string> hashSet = new HashSet<string>();
      List<string> list = new List<string>();
      for (int index = 0; index < this.Count; ++index)
      {
        ISortClause sortClause = this[index];
        string str;
        if (sortClause.FieldToSortCore.ExpressionToApply == null && sortClause.FieldToSortCore.AggregateFunctionToApply == AggregateFunction.None || !aliasesForExpressionsAggregates || (!sortClause.EmitAliasForExpressionAggregateField || sortClause.CaseSensitiveCollation))
        {
          str = this._databaseSpecificCreator.CreateFieldName(sortClause.FieldToSortCore, sortClause.PersistenceInfo, sortClause.FieldToSortCore.Alias, sortClause.ObjectAlias, true);
          if (sortClause.FieldToSortCore.ExpressionToApply != null && (!aliasesForExpressionsAggregates || !sortClause.EmitAliasForExpressionAggregateField))
            this._parameters.AddRange((IEnumerable<DbParameter>) sortClause.FieldToSortCore.ExpressionToApply.Parameters);
        }
        else
        {
          string alias = sortClause.FieldToSortCore.Alias;
          str = alias.IndexOf("(") >= 0 ? alias : this._databaseSpecificCreator.CreateValidAlias(sortClause.FieldToSortCore.Alias);
        }
        if (!hashSet.Contains(str))
        {
          hashSet.Add(str);
          if (sortClause.CaseSensitiveCollation)
            list.Add(string.Format("{0}({1}) {2}", (object) this._databaseSpecificCreator.ToUpperFunctionName(), (object) str, (object) this._databaseSpecificCreator.ConvertSortOperator(sortClause.SortOperatorToUse)));
          else
            list.Add(string.Format("{0} {1}", (object) str, (object) this._databaseSpecificCreator.ConvertSortOperator(sortClause.SortOperatorToUse)));
        }
      }
      return string.Join(", ", list.ToArray());
    }

The fist line in the method checks to determine whether or not the this._databaseSpecificCreator is null and throws an exception. This check is passed successfully. The code runs through the method until it reaches


if (sortClause.CaseSensitiveCollation)
            list.Add(string.Format("{0}({1}) {2}", (object) this._databaseSpecificCreator.ToUpperFunctionName(), (object) str, (object) this._databaseSpecificCreator.ConvertSortOperator(sortClause.SortOperatorToUse)));
          else
            list.Add(string.Format("{0} {1}", (object) str, (object) this._databaseSpecificCreator.ConvertSortOperator(sortClause.SortOperatorToUse)));

our expression is not using CaseSensitiveCollation, so we are with in the else statement. this is where this._databaseSpecificCreator, is now null. That is the issue we are seeing. As the call to ToQueryText is made from the DynamicQueryEngineBase AppendOrderByClause, The sort expression DatabaseSpecificCreate is set to the DynamicQueryEngineBase.Creator. I hope I have given you enough information. Please let me know if you need more details.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Dec-2014 06:38:59   

What is your app code that reproduces that problem? (i.e. How are you writing such SortExpressio)

David Elizondo | LLBLGen Support Team