可以将多个已编译的linq查询链接在一起吗? [英] Can multiple compiled linq queries be chained together?

查看:59
本文介绍了可以将多个已编译的linq查询链接在一起吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将多个已编译的linq查询链接在一起.我已经成功地将两个查询链接在一起,但是我无法获得三个查询的链接才能正常工作.因此,这里减少了我的代码来重新创建问题.我的两个问题是:为什么这不起作用?"和是否有更好的方法来保持编译查询的性能优势,并避免重复使用常用的基本查询逻辑?"

I am trying to chain multiple compiled linq queries together. I have succeeded in chaining two queries together, but I cannot get a chain of three to work correctly. So here is a reduction of my code to recreate the issue. My two questions are: 'Why isn't this working?' and 'Is there a better way to keep the performance benefit of compiled queries and also avoid duplication of base query logic that is commonly used?'

定义以下两个查询:

Func<DataContext, IQueryable<User>> selectUsers = 
    CompiledQuery.Compile(
        (DataContext dc)=>dc.Users.Select(x=>x)
    );
//        
Func<DataContext, string, IQueryable<User>> filterUserName = 
    CompiledQuery.Compile(
        (DataContext dc, string name) =>
            selectUsers(dc).Where(user=>user.Name == name)
    );

调用并枚举链条可以正常工作:

Calling and enumerating the chain works fine:

filterUserName(new DataContext(), "Otter").ToList();

向链中添加第三个查询:

Add a third query to the chain:

Func<DataContext, string, int, IQueryable<User>> filterUserAndGroup =     
    CompiledQuery.Compile(
        (DataContext dc, string name, int groupId) => 
            filterUserName(dc, name).Where(user=>user.GroupId == groupId)
    );

调用链不起作用:

filterUserAndGroup(new DataContext(), "Otter", 101);

System.InvalidOperationException: 用户"的成员访问字符串名称" 在类型上不合法 'System.Linq.IQueryable 1[User].. at System.Data.Linq.SqlClient.SqlMember.set_Expression(SqlExpression value) at System.Data.Linq.SqlClient.SqlFactory.Member(SqlExpression expr, MemberInfo member) at System.Data.Linq.SqlClient.SqlBinder.Visitor.AccessMember(SqlMember m, SqlExpression expo) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitMember(SqlMember m) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitBinaryOperator(SqlBinary bo) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitAlias(SqlAlias a) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlVisitor.VisitSource(SqlSource source) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitIncludeScope(SqlIncludeScope scope) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Bind(SqlNode node) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(ResultShape resultShape, Type resultType, SqlNode node, ReadOnlyCollection 1 parentParameters,SqlNodeAnnotations 注释) System.Data.Linq.SqlClient.SqlProvider.BuildQuery(表达式 查询,SqlNodeAnnotations批注) 在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Compile(表达式 查询) System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext 上下文,Object [] args)在 System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0,TArg1 arg1)在TestMethod()中 ....

System.InvalidOperationException: Member access 'String Name' of 'User' not legal on type 'System.Linq.IQueryable1[User].. at System.Data.Linq.SqlClient.SqlMember.set_Expression(SqlExpression value) at System.Data.Linq.SqlClient.SqlFactory.Member(SqlExpression expr, MemberInfo member) at System.Data.Linq.SqlClient.SqlBinder.Visitor.AccessMember(SqlMember m, SqlExpression expo) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitMember(SqlMember m) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitBinaryOperator(SqlBinary bo) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitAlias(SqlAlias a) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlVisitor.VisitSource(SqlSource source) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitIncludeScope(SqlIncludeScope scope) at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) at System.Data.Linq.SqlClient.SqlBinder.Bind(SqlNode node) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(ResultShape resultShape, Type resultType, SqlNode node, ReadOnlyCollection1 parentParameters, SqlNodeAnnotations annotations) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Compile(Expression query) at System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context, Object[] args) at System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0, TArg1 arg1) at TestMethod() in ....

推荐答案

看起来您需要在执行第二个查询之前将第一个编译查询转换为列表.从理论上讲,这也应该导致两个查询链出现错误.

Looks like you need to convert your first compiled query to a list before executing the second one. In theory that should have caused an error with your two queried chain as well.

来自 MSDN CompiledQuery :

如果将新的查询运算符应用于委托执行的结果,则会生成异常.

If a new query operator is applied to the result of the delegate execution, an exception is generated.

如果要对执行已编译查询的结果执行查询运算符,则必须先将结果转换为列表,然后再对其进行操作.

When you want to execute a query operator over the result of executing a compiled query, you must translate the result to a list before operating on it.

虽然如果使用LINQ to SQL,这可能会影响返回数据库的往返,但也许此代码将修复它.

Perhaps this code will fix it although that could have implications for the roundtrips back to the database if you're using LINQ to SQL.

filterUserName(dc, name).ToList().Where(user=>user.GroupId == groupId)

这篇关于可以将多个已编译的linq查询链接在一起吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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