This question is locked. New answers and comments are not allowed.
Have an MVC Grid that has filterable columns. I can click the little filter button in the column header and enter some text to filter on in the first or second filter box and it works fine. If I try to enter two filter conditions, say a starts with and an ends with, I get an error "an item with the same key has already been added" trying to get the matching rows from the database.
The GridCommand object passed by the Telerik Grid to my handler method looks correct. The CompositeFilterDescriptor has two FilterDescriptor objects filled in. The first is "AccountName StartsWith 'abc' " and the second is "AccountName EndsWith 'def' ". I create a "where clause" Telerik.Web.Mvc.ExpressionBuilder:
I create an NHibernate Query object and feed it the where:
Then try to get the count of rows that match the filter:
This call to Count gives the error. This works fine if there is only a single filter field entered into the Telerik MVC Grid's filter fields.
The where generated by the ExpressionBuilder looks OK to me. The Body contains a LogicalBinaryExpression, the left part is:
and the right part is:
Anyone else seen this?
The GridCommand object passed by the Telerik Grid to my handler method looks correct. The CompositeFilterDescriptor has two FilterDescriptor objects filled in. The first is "AccountName StartsWith 'abc' " and the second is "AccountName EndsWith 'def' ". I create a "where clause" Telerik.Web.Mvc.ExpressionBuilder:
Expression<Func<T, bool>> where = ExpressionBuilder.Expression<T>( command.FilterDescriptors);I create an NHibernate Query object and feed it the where:
IQueryable<T> query = session.Query<T>();if (where != null) query = query.Where(where);Then try to get the count of rows that match the filter:
int rowCount = query.Count();This call to Count gives the error. This works fine if there is only a single filter field entered into the Telerik MVC Grid's filter fields.
The where generated by the ExpressionBuilder looks OK to me. The Body contains a LogicalBinaryExpression, the left part is:
((IIF((item != null), item.AccountName, null) ?? "").ToLower().StartsWith("abc".ToLower()) == True)and the right part is:
((IIF((item != null), item.AccountName, null) ?? "").ToLower().EndsWith("def".ToLower()) == True)Anyone else seen this?
5 Answers, 1 is accepted
0
Dadv
Top achievements
Rank 1
answered on 09 Mar 2012, 09:41 AM
hi,
Could you copy/paste the entire error message and the grid/controller code please?
I often see this message when i try to return a view in ajax request instead of a partial view, so the entire page is resend (with the masterpage and the telerik script declaration). Telerik don't allow to assign it twice.
Could you copy/paste the entire error message and the grid/controller code please?
I often see this message when i try to return a view in ajax request instead of a partial view, so the entire page is resend (with the masterpage and the telerik script declaration). Telerik don't allow to assign it twice.
0
-glenn-
Top achievements
Rank 1
answered on 09 Mar 2012, 02:05 PM
That is the entire error message (An item with the same key has already been added.) There is no inner exception reported. Do you mean the stack trace?
The AJAX controller handler would return a ViewResult object with the Data and Total fields filled in, but it never gets that far because the call to Count gives the error. This very same action method works fine when there is no filters on the grid or there is only one filter on a grid column. The error occurs when there are two filters specified on a grid column.
The stack trace seems to indicate that NHibernate cannot deal with the "where" generated by the Telerik ExpressionBuilder:
The AJAX controller handler would return a ViewResult object with the Data and Total fields filled in, but it never gets that far because the call to Count gives the error. This very same action method works fine when there is no filters on the grid or there is only one filter on a grid column. The error occurs when there are two filters specified on a grid column.
The stack trace seems to indicate that NHibernate cannot deal with the "where" generated by the Telerik ExpressionBuilder:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)at NHibernate.Linq.Visitors.ExpressionParameterVisitor.VisitConstantExpression(ConstantExpression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\ExpressionParameterVisitor.cs:line 42at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitLambdaExpression(LambdaExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitUnaryExpression(UnaryExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](T expression, String methodName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.<>c__DisplayClass6`1.<VisitAndConvert>b__5(T expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](ReadOnlyCollection`1 expressions, String callerName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](T expression, String methodName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.<>c__DisplayClass6`1.<VisitAndConvert>b__5(T expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](ReadOnlyCollection`1 expressions, String callerName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](T expression, String methodName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.<>c__DisplayClass6`1.<VisitAndConvert>b__5(T expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](ReadOnlyCollection`1 expressions, String callerName) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression) in :line 0at Remotion.Data.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression) in :line 0at NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\NhExpressionTreeVisitor.cs:line 32at NHibernate.Linq.Visitors.ExpressionParameterVisitor.Visit(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\Visitors\ExpressionParameterVisitor.cs:line 20at NHibernate.Linq.NhLinqExpression..ctor(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\NhLinqExpression.cs:line 37at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line 41at NHibernate.Linq.NhQueryProvider.Execute(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line 26at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line 103at System.Linq.Queryable.Count[TSource](IQueryable`1 source)at Services.LookupTableServiceBase`1.GetLookupGrid(GridCommand command, IUserInfo`1 userInfo, String userNameMember) in G:\Services\LookupTableServiceBase.cs:line 169at Controllers.LookupTablesController.LookupIndex[T](GridCommand command, ILookupTableService`1 lookupService) in G:\Controllers\LookupTablesController.cs:line 80at Controllers.LookupTablesController._NicknameIndex(GridCommand command) in G:\Controllers\LookupTablesController.cs:line 471at lambda_method(Closure , ControllerBase , Object[] )at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)0
Dadv
Top achievements
Rank 1
answered on 09 Mar 2012, 02:23 PM
Could you provide a sample project please?
0
-glenn-
Top achievements
Rank 1
answered on 09 Mar 2012, 07:59 PM
Uh, not anytime soon. At least not a project that goes against a database and all that.
I've gone ahead and converted my code to use the technique from this library:
http://nuget.org/packages/TelerikMvcGridCustomBindingHelper.NHibernate
I ripped out some of the code and made some extensions. These use IQueryOver and populate the SQL where/sorting using a different technique than the way I was doing it before. I've attached the code for anyone who is interested.
I've gone ahead and converted my code to use the technique from this library:
http://nuget.org/packages/TelerikMvcGridCustomBindingHelper.NHibernate
I ripped out some of the code and made some extensions. These use IQueryOver and populate the SQL where/sorting using a different technique than the way I was doing it before. I've attached the code for anyone who is interested.
public static class GridExtensions{ public static IQueryOver ApplyGridSorting(this IQueryOver query, IList<SortDescriptor> sortDescriptors) { foreach (var sort in sortDescriptors.Reverse()) { var propertyName = sort.Member; int delim = propertyName.LastIndexOf('.'); if (delim != -1) propertyName = propertyName.Substring(delim+1); query.RootCriteria.AddOrder( sort.SortDirection == ListSortDirection.Descending ? Order.Desc(propertyName) : Order.Asc(propertyName)); } return query; } static IEnumerable<IFilterDescriptor> UnwrapFilterDescriptors( IEnumerable<IFilterDescriptor> filterDescriptors) { var result = new List<IFilterDescriptor>(); foreach (var filterDescriptor in filterDescriptors) { if (filterDescriptor.GetType() == typeof(FilterDescriptor)) result.Add(filterDescriptor); var compositeFilterDescriptor = filterDescriptor as CompositeFilterDescriptor; if (compositeFilterDescriptor != null) result.AddRange(UnwrapFilterDescriptors( compositeFilterDescriptor.FilterDescriptors)); } return result; } public static IQueryOver ApplyGridFilters(this IQueryOver query, IList<IFilterDescriptor> filterDescriptors) { if (!filterDescriptors.Any()) return query; var descriptors = UnwrapFilterDescriptors( filterDescriptors); foreach (var filter in descriptors .Cast<FilterDescriptor>() .Reverse()) { var propertyName = filter.Member; int delim = propertyName.LastIndexOf('.'); if (delim != -1) propertyName = propertyName.Substring(delim+1); query.ApplyGridFilter(filter, propertyName, filter.Operator); } return query; } public static IQueryOver ApplyGridFilter(this IQueryOver query, FilterDescriptor filter, string propertyName, FilterOperator filterOperator) { switch (filterOperator) { case FilterOperator.Contains: query.RootCriteria.Add(Restrictions.Like( propertyName, filter.Value.ToString(), MatchMode.Anywhere)); break; case FilterOperator.EndsWith: query.RootCriteria.Add(Restrictions.Like( propertyName, filter.Value.ToString(), MatchMode.End)); break; case FilterOperator.IsContainedIn: throw new NotSupportedException("Filter method " + "“IsContainedIn” is not supported."); case FilterOperator.IsEqualTo: query.RootCriteria.Add( Restrictions.Eq(propertyName, filter.Value)); break; case FilterOperator.IsGreaterThan: query.RootCriteria.Add(Restrictions.Gt( propertyName, filter.Value)); break; case FilterOperator.IsGreaterThanOrEqualTo: query.RootCriteria.Add(Restrictions.Ge( propertyName, filter.Value)); break; case FilterOperator.IsLessThan: query.RootCriteria.Add(Restrictions.Lt( propertyName, filter.Value)); break; case FilterOperator.IsLessThanOrEqualTo: query.RootCriteria.Add(Restrictions.Le( propertyName, filter.Value)); break; case FilterOperator.IsNotEqualTo: query.RootCriteria.Add( Restrictions.Not(Restrictions.Eq(propertyName, filter.Value))); break; case FilterOperator.StartsWith: default: query.RootCriteria.Add(Restrictions.Like( propertyName, filter.Value.ToString(), MatchMode.Start)); break; } return query; }}0
-glenn-
Top achievements
Rank 1
answered on 10 Mar 2012, 04:15 PM
I have asked about this in the nhusers group too:
Error: An item with the same key has already been added
Error: An item with the same key has already been added