- Home
- LLBLGen Pro
- Bugs & Issues
NullReferenceException - SortExpression ToQueryText
Joined: 05-Dec-2014
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)
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);
}
Joined: 05-Dec-2014
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.