I try to use Count() from Dynamic Linq Library http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx in simple queries it's ok, but in ExecuteFutureScalar I got exception: Unable to translate 'Query.All() as IQueryable.Count()' expression. See inner exception for details. inner: {"Unable to cast object of type 'System.Linq.Expressions.MethodCallExpression' to type 'Xtensive.Storage.Linq.Expressions.ProjectionExpression'."}

var countSimple = (Query.All<FieldType>() as IQueryable).Count();
var countFuture = Query.ExecuteFutureScalar(() => (Query.All<FieldType>() as IQueryable).Count());

actualy safe cast to IQueryable is used to simulate this things:

var type = typeof(FieldType);
            IQueryable queryable1 = GetQueryable(type);

where

IQueryable GetQueryable(Type type)
        {
            MethodInfo method;
            ParameterInfo[] parameters;
            ReflectionHelper.FindMethod(typeof(Query), "All", new[] { type }, new Type[0], out method, out parameters);
            var qu = method.Invoke(null, null);
            return qu as IQueryable;
        }

Updated at 31.03.2010 12:53:39

Problem only in ExecuteFutureScalar, var countSimple = (Query.All<fieldtype>() as IQueryable).Count(); - works ok


Updated at 07.04.2010 11:40:36

This works with execute future:

public static Expression<Func<int>> FutureCount(this IQueryable source)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            return Expression.Lambda<Func<int>>(
                                                Expression.Call(
                                                                typeof(Queryable), "Count",
                                                                new Type[] { source.ElementType }, source.Expression));
        }

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Mar 31 '10 at 09:59

pil0t's gravatar image

pil0t
207555763

Most likely the issue is that IQueryable.Count is really not supported (although IQueryable<t>.Count is supported).

LINQ guys (from our team), could you comment this? Workarounds? What must be done at our side?

(Mar 31 '10 at 09:59) Alex Yakunin Alex%20Yakunin's gravatar image
(Mar 31 '10 at 09:59) Alex Yakunin Alex%20Yakunin's gravatar image

One Answer:

The issue status is set to invalid: Dynamic LINQ builds its own IQueryable with its own method invocations, which are transformed to actual IQueryable it "wraps" only on its enumeration or execution (i.e. when either GetEnumerator() or Count()-like extension method is called).

Thus such queryables really can't be processed by our ExecuteXxx methods: there is no way to extract our own underlying IQueryable from them without invoking either GetEnumerator() or Count()-like method on them, that makes such an attempt practically useless.

So the only solution is to avoid using Query.ExecuteXxx methods in this case.


As far as I can judge, there is no such way. Of course, if Dynamic LINQ is capable of returning an expression it produces, or an IQueryable, this must be possible. But I'm not familiar with it so deeply.

Btw, is it really not acceptable to avoid usign ExecuteFutureScalar here? It's just an optimization (and moreover, specific to DO), and you're padding a dynamic query to this method. Normally it's ok to have an additional roundrip to the database in such a case ;) (i.e. with any other ORM you'd have exactly this case).


Any IQueryable has this property - its value describes transformations performed on original queryables to produce this one. I.e. in fact, there is "recorded" sequence of method calls like .Where, that were executed to produce this queryable.

So I'm 99% sure this is not a translated expression, but the original one. To check this, you can call our .ToString(true) extension method on this Expression object.


Err... As far as I can judge, it builds an expression, that is equal to (... as IQueryable).Count() - i.e. the same expression.

So you mean this query really work as future query:

var countFuture = Query.ExecuteFutureScalar(() => (Query.All<FieldType>() as IQueryable).FutureCount());?

answered Apr 01 '10 at 11:24

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

So, is there any way to dynamicaly generate query (with where) for use in ExecuteFutureScalar() with Count() ?

(Apr 01 '10 at 11:24) pil0t pil0t's gravatar image

IQuryable from DLINQ has its Expression property

(Apr 01 '10 at 11:24) xumix xumix's gravatar image

The bug was fixed today. See nightly build.

(Apr 01 '10 at 11:24) Dmitri Maximov Dmitri%20Maximov's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×569

Asked: Mar 31 '10 at 09:59

Seen: 1,810 times

Last updated: Mar 31 '10 at 09:59

powered by OSQA