加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何获取ToTraceString for IQueryable.Count

发布时间:2020-12-15 06:34:52 所属栏目:百科 来源:网络整理
导读:我使用((ObjectQuery)IQueryable).ToTraceString()来获取和调整将要由LINQ执行的SQL代码. 我的问题是,不像大多数IQueryable方法IQueryable.Count定义如下: public static int Count(this IQueryable source) { return (int)source.Provider.Execute( Expres
我使用((ObjectQuery)IQueryable).ToTraceString()来获取和调整将要由LINQ执行的SQL代码.

我的问题是,不像大多数IQueryable方法IQueryable.Count定义如下:

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

执行查询而不编译并返回IQueryable.
我想这样做的伎俩:

public static IQueryable CountCompile(this IQueryable source) {
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable),source.Expression));
}

但是,然后CreateQuery给我以下异常:

LINQ to Entities查询表达式只能从实现IQueryable接口的实例中构建.

解决方法

当我尝试这样做时,我想出了一个实际的工作答案.异常说“只能从实现IQueryable接口的实例构造”,所以答案看起来很简单:返回一个可查询的东西.返回.Count()可以这样吗?是!
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查询.它将查询转换为

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

除了让上下文的QueryProvider处理查询.生成的SQL几乎是你应该期望的:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读