如何获取ToTraceString为IQueryable.Count [英] How to obtain ToTraceString for IQueryable.Count

查看:925
本文介绍了如何获取ToTraceString为IQueryable.Count的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用((的ObjectQuery)的IQueryable).ToTraceString()来获取和调整就是要通过LINQ执行的SQL代码。

I use ((ObjectQuery)IQueryable).ToTraceString() to obtain and tweak SQL code that is going to be executed by LINQ.

我的问题是,不像大多数的IQueryable方法IQueryable.Count为这样定义的:

My problem is that unlike most IQueryable methods IQueryable.Count as defined like this:

    public static int Count(this IQueryable source) {
        return (int)source.Provider.Execute(
            Expression.Call(
                typeof(Queryable), "Count",
                new Type[] { source.ElementType }, source.Expression));
    }



执行查询,无需编译并返回IQueryable的。
我希望通过这样的事情做的伎俩:

executes query without compiling and returning IQueryable. I wanted to do the trick by something like this:

public static IQueryable CountCompile(this IQueryable source) {
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable), "Count",
            new Type[] { source.ElementType }, source.Expression));
}



但随后的createQuery给了我以下异常:

But then CreateQuery gives me the following exception:

LINQ到实体查询表达式只能从实现的IQueryable接口实例构造。

推荐答案

这是我来到了,当我试图让相同的实际工作答案。唯一的例外说,所以答案似乎很简单只能从实现了IQueryable的接口实例构造:返回一个可查询的东西。这是可能的返回时,一个 .Count之间的()?是的!

Here's an actual working answer I came up with when I tried to so the same. The exception says "can only be constructed from instances that implement the IQueryable interface", so the answer seems simple: return a queryable something. Is that possible when returning a .Count()? Yes!

public partial class YourObjectContext
{
    private static MethodInfo GetMethodInfo(Expression<Action> expression)
    {
        return ((MethodCallExpression)expression.Body).Method;
    }
    public IQueryable<TResult> CreateScalarQuery<TResult>(Expression<Func<TResult>> expression)
    {
        return QueryProvider.CreateQuery<TResult>(
            Expression.Call(
                method: GetMethodInfo(() => Queryable.Select<int, TResult>(null, (Expression<Func<int, TResult>>)null)),
                arg0: Expression.Call(
                    method: GetMethodInfo(() => Queryable.AsQueryable<int>(null)),
                    arg0: Expression.NewArrayInit(typeof(int), Expression.Constant(1))),
                arg1: Expression.Lambda(body: expression.Body, parameters: new[] { Expression.Parameter(typeof(int)) })));
    }
}

要使用它:

var query = context.CreateScalarQuery(() => context.Entity.Count());
MessageBox.Show(((ObjectQuery)query).ToTraceString());



基本上,这确实是子查询包裹非IQueryable的查询。它把从假人在新的INT [] {1} .AsQueryable()
选择环境中的查询到

Basically, what this does is wrap a non-IQueryable query in a subselect. It transforms the query into

from dummy in new int[] { 1 }.AsQueryable()
select context.Entity.Count()

除了让上下文的QueryProvider处理查询。生成的SQL是相当多的,你应该期待什么:

except lets the context's QueryProvider handle the query. The generated SQL is pretty much what you should expect:

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[Entity] AS [Extent1]
)  AS [GroupBy1]

这篇关于如何获取ToTraceString为IQueryable.Count的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆