Problem in Linq query compiler

5 posts, 0 answers
  1. Noam Berda
    Noam Berda avatar
    10 posts
    Member since:
    Mar 2007

    Posted 10 Oct 2011 Link to this post

    Hi,
    I have a short code that add dynamically order by query to an existing query.
    This code works fine on EF4.1 but doesn't work on Telerik ORM.

    Here is the exception
    System.NullReferenceException: Object reference not set to an instance of an object. at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQueryImpl(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid) at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid)

    here is the linq query that been built
    {Extent<XXXX.DB.Report>().Where(x => (x.inStatus == Convert(value(XXXXX.Services.Services.ReportService+<>c__DisplayClass2).statusFilter))).OrderBy(Param_0 => Param_0.Address)}

    And here is the code that creates it. i think its a problem with Param_0 variable name, but this the default name when i am using the Parameter expression.
    public IQueryable<T> ApplyOrder(IQueryable<T> source)
            {
     
                var sortOrder = (_sortOrder == SortOrder.Ascending) ?
                                    "OrderBy" : "OrderByDescending";
                
     
                ParameterExpression[] parameters = new ParameterExpression[] {
                    Expression.Parameter(typeof(T)) };
     
                //Dig into lambda expression
                Type fieldType = null;
                MemberExpression memberExpression = null;
                Type t = typeof(T);
                string[] tokenFieldName = _orderByField.Split('.');
                
                foreach (var s in tokenFieldName)
                {
                    var properties = TypeDescriptor.GetProperties(t);
                    var property = properties[s];
                    if (property != null)
                    {
                        t = fieldType = property.PropertyType;
                        if (memberExpression == null)
                        {
                            memberExpression = Expression.Property(parameters[0], s);
                        }
                        else
                        {
                            memberExpression = Expression.Property(memberExpression, s);
                        }
                    }
                    else
                    {
                        throw new Exception(string.Format("Cannot find field with name '{0}'", _orderByField));
                    }
                }
     
                if (memberExpression != null)
                {
                    Expression queryExpr = Expression.Call(
                        typeof(Queryable), sortOrder,
                        new Type[] { typeof(T), fieldType },
                        source.Expression, Expression.Quote(Expression.Lambda(memberExpression, parameters)));
                    source = source.Provider.CreateQuery<T>(queryExpr);
     
                    return source;
                }
                else
                {
                    throw new NullReferenceException("No memberExpression was constructed");
                }
                
            }


  2. Thomas
    Admin
    Thomas avatar
    590 posts

    Posted 11 Oct 2011 Link to this post

    Hi Noam Berda,

    I can't find an issue there. I've used your code, and the ordering is doing what it should do.
    So, there it could be bound to the inStatus field and the parameter; of which type are they?

    Best wishes,
    Thomas
    the Telerik team

    Check out the latest stable build of Telerik OpenAccess ORM. Download it and benefit from our new Project Templates.

  3. DevCraft banner
  4. Noam Berda
    Noam Berda avatar
    10 posts
    Member since:
    Mar 2007

    Posted 11 Oct 2011 Link to this post

    Hi Thomas,
    I have tried to reproduce it for you so you can see the problem. It looks related to the way the param name are been translated. when i am writing the same query in linq then i can see the param name some how get translated to var1. but when i am using the sample code i gave you the param name is kept at "Param_0" i have seen it when i am looking on the Expression.DebugView of the query and comparing the linq vs ApplyOrder method.

    Here is how to reproduce it. take your context, and get all the objects of specific entity. (I am using my Report object but i think it will work on any one). Then apply the order filter to the query with the field name and call ToList. it should then throw the exception.

    Hope you can reproduce it.
    Noam

    var q = _xxxxeContext.Reports;
    q = ApplyOrder(q, "Address");
    var g = q.ToList();
    
    use the following method to apply the order by.
    
    
           public IQueryable<T> ApplyOrder<T>(IQueryable<T> source, string fieldName)
            {
     
                var sortOrder = "OrderBy";
     
     
                ParameterExpression[] parameters = new ParameterExpression[] {
                    Expression.Parameter(typeof(T)) };
     
                //Dig into lambda expression
                Type fieldType = null;
                MemberExpression memberExpression = null;
                Type t = typeof(T);
                string[] tokenFieldName = new string[] { fieldName };
     
                foreach (var s in tokenFieldName)
                {
                    var properties = TypeDescriptor.GetProperties(t);
                    var property = properties[s];
                    if (property != null)
                    {
                        t = fieldType = property.PropertyType;
                        if (memberExpression == null)
                        {
                            memberExpression = Expression.Property(parameters[0], s);
                        }
                        else
                        {
                            memberExpression = Expression.Property(memberExpression, s);
                        }
                    }
                }
     
                if (memberExpression != null)
                {
                    Expression queryExpr = Expression.Call(
                        typeof(Queryable), sortOrder,
                        new Type[] { typeof(T), fieldType },
                        source.Expression, Expression.Quote(Expression.Lambda(memberExpression, parameters)));
                    source = source.Provider.CreateQuery<T>(queryExpr);
     
                    return source;
                }
                else
                {
                    throw new NullReferenceException("No memberExpression was constructed");
                }
     
            }
  5. Thomas
    Admin
    Thomas avatar
    590 posts

    Posted 12 Oct 2011 Link to this post

    Hello Noam Berda,

    I've rechecked and even used your code in our test suite, but I'm afraid I do not see the effect. Are you really using the latest version ? Older versions did rely on the name of the parameters, newer versions rely on the reference of the parameter expression. You can also give the parameter an explicit name to see if Param_0 is really an issue (again, not on my side).

    All the best,
    Thomas
    the Telerik team

    Check out the latest stable build of Telerik OpenAccess ORM. Download it and benefit from our new Project Templates.

  6. Noam Berda
    Noam Berda avatar
    10 posts
    Member since:
    Mar 2007

    Posted 13 Oct 2011 Link to this post

    Hi Thomas,
    I have checked and i am using the latest ORM release.
    I have found a workaround for now and will continue to monitor this and will let you know if its coming back.

    the workaround was to change the order when i build the linq statement. apparently it solved the problem.

    Noam
Back to Top
DevCraft banner