Filter inssues using server side predicates

Posts   
 
    
Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 20-Sep-2006 08:16:54   

Hi People,

Ima hving trouble with filtering, Im using Adapter + 2.0 to filter my table by like so:



IPredicateExpression filter = new PredicateExpression();
EntityField2 entityField2 = new EntityField2("Name", null);
filter.Add(entityField2 == DBNull.Value);


Then passing that to:



try
{
adapter.FetchEntityCollection(collection, filter, numberOfRecordsToReturn, null, null, pageNumber, pageSize);
return collection;
}
catch (ORMQueryExecutionException ex)
{
BaseManagerException Ex = new BaseManagerException(ex.QueryExecuted, ex);
Log.Error("Collection Fetch Failed.", Ex);
throw Ex;
}


But i keep getting this null refrence exception:



{"Object reference not set to an instance of an object."}

  at SD.LLBLGen.Pro.ORMSupportClasses.Expression.OperandToText(StringBuilder& queryText, IExpressionElement operand, Int32& uniqueMarker, Boolean isLeftOperand, Boolean inHavingClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.Expression.ToQueryText(Int32& uniqueMarker, Boolean inHavingClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.DbSpecificCreatorBase.ConvertFieldToRawName(IEntityFieldCore fieldCore, IFieldPersistenceInfo persistenceInfo, String fieldName, String objectAlias, Int32& uniqueMarker, Boolean applyAggregateFunction)
   at SD.LLBLGen.Pro.DQE.SqlServer.SqlServerSpecificCreator.CreateFieldName(IEntityFieldCore fieldCore, IFieldPersistenceInfo persistenceInfo, String fieldName, String objectAlias, Int32& uniqueMarker, Boolean applyAggregateFunction)
   at SD.LLBLGen.Pro.ORMSupportClasses.FieldCompareNullPredicate.ToQueryText(Int32& uniqueMarker, Boolean inHavingClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression.ToQueryText(Int32& uniqueMarker, Boolean inHavingClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression.ToQueryText(Int32& uniqueMarker, Boolean inHavingClause)
   at SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression.ToQueryText(Int32& uniqueMarker)
   at SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, 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, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause)
   at SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CreatePagingSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
   at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.CreateSelectDQ(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfoObjects, IPredicateExpression filter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollectionInternal(IEntityCollection2 collectionToFill, IRelationPredicateBucket& filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, Int32 pageNumber, Int32 pageSize)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, Int32 pageNumber, Int32 pageSize)
   at CS.BusinessLogicLayer.BaseManager`1.FetchCollection(EntityCollection`1 collection, IRelationPredicateBucket filter, Int32 numberOfRecordsToReturn, ISortExpression sorter, IPrefetchPath2 prefetch, Int32 pageNumber, Int32 pageSize, IDataAccessAdapter adapter) in C:\CS\Compu-Stor2005\Application\CS.BusinessLogicLayer\BusinessManager\BaseManager.cs:line 698
   at CS.BusinessLogicLayer.BaseManager`1.FetchCollection(EntityCollection`1 collection, IRelationPredicateBucket filter, Int32 numberOfRecordsToReturn, ISortExpression sorter, IPrefetchPath2 prefetch, Int32 pageNumber, Int32 pageSize) in C:\CS\Compu-Stor2005\Application\CS.BusinessLogicLayer\BusinessManager\BaseManager.cs:line 676
   at CS.BusinessLogicLayer.CustomerManager.FetchPagedCustomerCollection(Int32 startRowIndex, Int32 pageSize, IRelationPredicateBucket filter, ISortExpression sort, IPrefetchPath2 path) in C:\CS\Compu-Stor2005\Application\CS.BusinessLogicLayer\BusinessManager\CustomerManagerBase.cs:line 154
   at CS.BusinessLogicLayer.CustomerManager.GetAllParentCustomers(Int32 startRowIndex, Int32 pageSize, ISortExpression sort, IPredicateExpression filter) in C:\CS\Compu-Stor2005\Application\CS.BusinessLogicLayer\BusinessManager\CustomerManager.cs:line 93
   at Secure_ViewCustomers.radgCustomers_NeedDataSource(Object source, GridNeedDataSourceEventArgs e) in c:\CS\Compu-Stor2005\Application\CS.Web\Secure\ViewCustomers.aspx.cs:line 44
   at Telerik.WebControls.RadGrid.OnNeedDataSource(GridNeedDataSourceEventArgs e)
   at Telerik.WebControls.RadGrid.ObtainDataSource(GridRebindReason rebindReason, Boolean IsBoundUsingDataSourceId)
   at Telerik.WebControls.GridTableView.ObtainDataSource(GridRebindReason rebindReason)
   at Telerik.WebControls.GridTableView.Rebind()
   at Telerik.WebControls.GridFilterCommandEventArgs.ExecuteCommand(Object source)
   at Telerik.WebControls.RadGrid.OnBubbleEvent(Object source, EventArgs e)
   at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
   at Telerik.WebControls.GridItem.OnBubbleEvent(Object source, EventArgs e)
   at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
   at Telerik.WebControls.GridItem.OnBubbleEvent(Object source, EventArgs e)
   at Telerik.WebControls.GridItem.FireCommandEvent(String commandName, Object commandArgument)
   at Telerik.WebControls.RadGrid.FilteringMenuItemOnClick(GridMenuItem menuItem, GridMenuItemClickEventArgs e)
   at Telerik.WebControls.GridMenuItem.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


I have tried heaps of diffrent things and it just not working for me. Any clues to what I'm doing wrong?

Thanks Heaps and sorry for the stupid questions! -M

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 20-Sep-2006 08:34:46   

Try to use the FieldCompareNullPredicate constructor instead:

FieldCompareNullPredicate( 
   IEntityFieldCore field,
   IFieldPersistenceInfo persistenceInfo,
   string objectAlias,
   bool negate
)
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 20-Sep-2006 09:51:35   

also, use the real field, not: EntityField2 entityField2 = new EntityField2("Name", null); but for example: IPredicateExpression filter = new PredicateExpression(); filter.Add(CustomerFields.CompanyName == DBNull.Value);

Frans Bouma | Lead developer LLBLGen Pro
Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 20-Sep-2006 12:14:48   

Hi Guys,

Thanks for the really quick reponses (you guys are legends in support):

I tried this:



// Worked.
A.Add(new FieldCompareNullPredicate(CustomerFields.Name, null)); 

// Worked.
A.Add(CustomerFields.Name == DBNull.Value); 

// Failed.
EntityField2 entityField2 = new EntityField2("Name", null);
filter.Add(new FieldCompareNullPredicate(entityField2, null)); 


I would use the CustomerField.Name normally but in this situation I need to be able just to pass the field name in as a string. Its for filtering of a data grid and I dont know which field the user will filter on. So any ideas what I'm missing for the EntityField2("Name", null); constructor?

I noticed I had the similar problem with the sort and the entity field for example:



string FieldName = "Name";

// This Works:
EntityField2 entityField2 = new EntityField2(FieldName, new Expression());
clause = new SortClause(entityField2, null, SortOperator.Descending);

//This fails (null refrence exception):
EntityField2 entityField2 = new EntityField2(FieldName, null);
clause = new SortClause(entityField2, null, SortOperator.Descending);


But that hasn't helped solve the isue with the filtering rage

Any ideas?

Thanks heaps! -M

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 20-Sep-2006 15:03:14   

How do you create the "collection" passed to the fetch method?

Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 21-Sep-2006 02:40:42   

Hi Walaa,



EntityCollection<CustomerEntity> customerCollection = new EntityCollection<CustomerEntity>(new CustomerEntityFactory());
return FetchCollection(customerCollection, filter, sort, path, pageIndex, pageSize);


Anything im missing from that?

Thanks! A

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 21-Sep-2006 09:21:24   

Anything im missing from that?

No, I thought you did not know which entity you are filtering on.

But I went back to your previous messages and it was "I dont know which field the user will filter on."

You can create a switch/case to return the appropriate EntityField.


EntityField2 entityField2;
Switch (userSelectedFilter)
{
case "Name":
entityField2 = CustomerFields.CompanyName;
.
.
.
}

Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 21-Sep-2006 09:58:12   

Hi Walaa,

Thanks for you reponse, but in this situation I don't know what entity will be nor do I know what field will be. I just gave you an example of one of the enities being created. A case statment crosses me as a bad idea. plus if I knew what entity it was going to be why not just use enum.parse?

I'm trying to write a simple predicate generator that will except a fieldname as a string, a comparision oprator as a string / enum and a value as a string. The predicate will be then be passed to the business layer, enabling filtering on any of my collections in the application in a generic manner for databinding.

I'm a bit confused why the simple string constructor of the entityfield2 doesn't work.

So any idea why the fieldentity string based constructor throws an error and how can I fix it?

Thanks heaps M

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 21-Sep-2006 15:51:23   

please, check this thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=738

Tell me if it's irrelevant to your situation.

Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 22-Sep-2006 04:23:53   

Hi Walaa,

Thats a cool example! but its far in excess of what I need. All I really need is an option that lets me say:



       public IPredicate CreateFilter(string fieldName, Operator operatorType, string fieldvalue)
        {
            EntityField2 entityField2 = new EntityField2(fieldName, new Expression(), AggregateFunction.None);

            switch (operatorType)
            {
                case Operator.IsNull:
                    return new FieldCompareNullPredicate(entityField2, null);

                case Operator.IsLike:
                    return new FieldLikePredicate(entityField2, null, fieldvalue, null);

                case Operator.IsEqual:
                    return new FieldCompareValuePredicate(entityField2, null, ComparisonOperator.Equal, fieldvalue);
            }
        }

        public enum Operator
        {
            IsNull, IsLike, IsEqual
        }


So are you guys saying I have to specifiy the field using the Fieldsnum.FieldName option? I didn't imagine filtering by a field name string would be so much trouble.

The reason I'm doing all this is beacuse I need to convert the RAD grid (by telerik) filterexpression into a predicate that I can then pass onto the business object.

Thanks M

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Sep-2006 08:13:36   

The field's persistence info is needed in filtering. Like the table name is used as well as the field name to construct the predicate. Because you can't depend on the field name only, this can generate errors in the produced SQL query. (in case the field name is ambiguous, i.e. exists in more than one object in the query)

Maxus
User
Posts: 76
Joined: 04-Aug-2006
# Posted on: 25-Sep-2006 03:48:10   

Hi Walaa,

Once I knew that you cant create predicates witout knowing the entity type, Made the whole thing a bit eaiser but sadly a little less flexible.


        public static IPredicateExpression Convert(GridColumnCollection Columns, EntityType entityType)
        {

            IPredicateExpression filterExpression = new PredicateExpression();

            EntityFields2 EntityFieldsCollection = (EntityFields2)EntityFieldsFactory.CreateEntityFieldsObject(entityType);

            foreach (GridColumn column in Columns)
            {
                IEntityField2   filterField = EntityFieldsCollection[column.UniqueName];
                string        filterValue = column.CurrentFilterValue.ToUpper();
                IPredicate    predicate = null; 

Do what you want to create expression here.


This works well to conver the rad grid filtering to a predicate. Thanks for eveyones help!

Cheers M