This is a migrated thread and some comments may be shown as answers.

Grid and OData's Filter options

8 Answers 153 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Dimitar
Top achievements
Rank 1
Dimitar asked on 12 Aug 2011, 05:45 PM
Hi guys:)

When the grid is bound to a WCF OData Service, trying to filter by a string column throws the following NotSupportedException (StackTrace is a the end of the post):

"The expression (([10007].RoleName ?? "").ToLower().StartsWith("role1") == True) is not supported."

The problem seems to be that OData's Filter options do not support the null coalescence. The filter options description at odata.org says the following:

"Note: ISNULL or COALESCE operators are not defined. Instead, there is a null literal which can be used in comparisons."

After some digging in the source, we found where the coalesce expression is created and temporarily removed the call:

\Telerik.Web.Mvc\Infrastructure\Implementation\Filtering\FilterOperatorExtensions.cs ln 167:
var liftedToEmpty = ExpressionFactory.LiftStringExpressionToEmpty(stringExpression);

It's possible that similar problems with OData limitations lurk in other parts of the code, but we didn't dig further. It would be great if there is an official fix for the issue in next versions.

Regards,
Dimitar Milushev

P.S. StackTrace for the exceptions, if it's of any help:

 at System.Data.Services.Client.ExpressionWriter.ExpressionToString(DataServiceContext context, Expression e)
   at System.Data.Services.Client.UriWriter.VisitQueryOptionExpression(FilterQueryOptionExpression fqoe)
   at System.Data.Services.Client.UriWriter.VisitQueryOptions(ResourceExpression re)
   at System.Data.Services.Client.UriWriter.VisitResourceSetExpression(ResourceSetExpression rse)
   at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
   at System.Data.Services.Client.UriWriter.Translate(DataServiceContext context, Boolean addTrailingParens, Expression e, Uri& uri, Version& version)
   at System.Data.Services.Client.DataServiceQueryProvider.Translate(Expression e)
   at System.Data.Services.Client.DataServiceQuery`1.get_QueryComponents()
   at System.Data.Services.Client.DataServiceRequest.GetQuerySetCount(DataServiceContext context)
   at System.Data.Services.Client.DataServiceQueryProvider.ReturnSingleton[TElement](Expression expression)
   at System.Data.Services.Client.DataServiceQueryProvider.Execute[TResult](Expression expression)
   at Telerik.Web.Mvc.Extensions.QueryableExtensions.Count(IQueryable source) in C:\Users\developer-100\Documents\Telerik_Extensions_for_ASPNET_MVC_2011_2_712_OpenSource\Source\Telerik.Web.Mvc\Extensions\QueryableExtensions.cs:line 451
   at Telerik.Web.Mvc.Extensions.QueryableExtensions.ToGridModel(IQueryable queryable, Int32 page, Int32 pageSize, IList`1 sortDescriptors, IEnumerable`1 filterDescriptors, IEnumerable`1 groupDescriptors) in C:\Users\developer-100\Documents\Telerik_Extensions_for_ASPNET_MVC_2011_2_712_OpenSource\Source\Telerik.Web.Mvc\Extensions\QueryableExtensions.cs:line 89
   at Telerik.Web.Mvc.UI.GridDataProcessor.EnsureDataSourceIsProcessed() in C:\Users\developer-100\Documents\Telerik_Extensions_for_ASPNET_MVC_2011_2_712_OpenSource\Source\Telerik.Web.Mvc\UI\Grid\GridDataProcessor.cs:line 247
   at Telerik.Web.Mvc.UI.GridDataProcessor.get_ProcessedDataSource() in C:\Users\developer-100\Documents\Telerik_Extensions_for_ASPNET_MVC_2011_2_712_OpenSource\Source\Telerik.Web.Mvc\UI\Grid\GridDataProcessor.cs:line 137
   at Telerik.Web.Mvc.GridActionAttribute.OnActionExecuted(ActionExecutedContext filterContext) in C:\Users\developer-100\Documents\Telerik_Extensions_for_ASPNET_MVC_2011_2_712_OpenSource\Source\Telerik.Web.Mvc\UI\Grid\GridActionAttribute.cs:line 171
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)

8 Answers, 1 is accepted

Sort by
0
Rosen
Telerik team
answered on 15 Aug 2011, 10:57 AM
Hello Dimitar,

Could you please provide a small sample in which this error can be observed locally? This way we will be able to get better understanding about your scenario and if possible provide a fix.

Regards,
Rosen
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

0
Dimitar
Top achievements
Rank 1
answered on 16 Aug 2011, 02:37 PM
Hi,

I'm attaching the sample project. Let me know if you have any questions.
0
Rosen
Telerik team
answered on 16 Aug 2011, 04:49 PM
Hi Dimitar,

Thank you for the sample project. We have able to address the described error and I have attached an internal build. Please give it a spin and let us know if it helps.

Regards,
Rosen
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

0
Dimitar
Top achievements
Rank 1
answered on 17 Aug 2011, 11:41 AM
Thank you very much! It works perfectly:)

There is a second 'issue' demonstrated in the project. You can see it by clicking on the "Custom Objects" button in the top right. The problem is that when the Grid tries to sort the data after we've called 'select' to transform the data, the WCF DS throws an exception. My question is, do you think there is an easy workaround for that or Custom Binding is our only option in this case?
0
Rosen
Telerik team
answered on 17 Aug 2011, 12:22 PM
Hi Dimitar,

The error you are observing is expected. Generally speaking there is no LINQ providers which will handle such constructs in all scenarios.

The easy workaround will be to evaluate (by calling ToList for example) the result query before it is passed to GridModel. However, the drawback will be that than the paging, sorting etc. will be executed in-memory.

Another not-so-easy approach will be indeed to use custom binding.

Best wishes,
Rosen
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

0
Sylvia
Top achievements
Rank 1
answered on 25 Aug 2011, 12:04 PM
Hi, Rosen!

My name is Sylvia and I am a colleague of Dimitar's.
First of all, thank you for your fast fix of our previous issue!

We decided to use custom binding in order to address the problem with custom models.
We tried using some of the sample code you have provided for building a custom filtering expression:

ExpressionBuilder.Expression<T>(filterDescriptors)

However, we ran into another exception related to OData Services operation restrictions. We get the following error:

The expression ((IIF(([10007] != null), [10007].FirstName, null) ?? "").ToLower() == "nancy") is not supported.

I think it is pretty much the same issue as the one above - the OData Services do not support coalesce expressions and the property which decides whether to use a coalesce expression (ExpressionBuilderOptions.LiftMemberAccessToNull) seems to be always true.

Please find a sample project attached.

Best Regards,
Sylvia Vassileva
0
Rosen
Telerik team
answered on 25 Aug 2011, 12:47 PM
Hi Sylvia,

Although, in the library the method use the in sample you have provided, is not intended to be used with infinite number of LINQ providers but only to illustrate a possible usage with LinqToSql implementation of custom binding example. 

Usually similar to the sample you have attached when a custom binding is used thus the built-in functionality is skipped, the developer is in charge to provide a binding implementation appropriate for his scenario as in this case our grid component expects the already processed data.

All the best,
Rosen
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Sylvia
Top achievements
Rank 1
answered on 25 Aug 2011, 04:16 PM
Hi Rosen!

I see your point. Thank you for your time!

Best Regards,
Sylvia Vassileva
Tags
Grid
Asked by
Dimitar
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Dimitar
Top achievements
Rank 1
Sylvia
Top achievements
Rank 1
Share this question
or