Linq to SQL DynamicInvoke(System.Object[])'不支持 SQL 转换
我有一个类,用户。
Users 有一个 UserId 属性。
我有一个看起来像这样的方法:
static IQueryable<User> FilterById(this IQueryable<User> p, Func<int, bool> sel)
{
return p.Where(m => sel(m.UserId));
}
不可避免地,当我调用该函数时:
var users = Users.FilterById(m => m > 10);
我收到以下异常:
方法“System.Object DynamicInvoke(System.Object[])”没有 支持 SQL 翻译。
这个问题有什么解决办法吗?我可能需要在 Expression.KillMeAndMyFamily() 的兔子洞里走多远?
为了澄清我为什么这样做:我使用 T4 模板自动生成一个简单的存储库和管道系统。在管道中,我不想写:
new UserPipe().Where(m => m.UserId > 10 && m.UserName.Contains("oo") && m.LastName == "Wee");
我想生成类似的东西:
new UserPipe()
.UserId(m => m > 10)
.UserName(m => m.Contains("oo"))
.LastName("Wee");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我们以
UserId
为例。你想要写:并希望这与:
你需要做的是获取第一个版本的表达式树并将其转换为第二个版本。
因此,首先更改
UserId
的签名以接受表达式树而不是已编译的 lambda:然后,编写一个将第一个表达式树转换为第二个版本的方法。让我们看一下两个表达式树:
输入:
输出:
正如你所看到的,你需要做的就是获取 lambda 的主体,递归地替换所有出现的地方参数
uid
和参数user
上的属性UserId
并使用转换后的主体和参数user 创建一个新的 lambda 表达式
。您可以使用 ExpressionVisitor 进行替换。
Let's take
UserId
as an example. You want to write:and want this to be the same as:
What you need to do is to take the expression tree of the first version and translate it to the second version.
So, first change the signature of
UserId
to accept an expression tree instead of a compiled lambda:Then, write a method that converts the first expression tree to the second version. Let's have a look at the two expression trees:
Input:
Output:
As you can see, all you need to do is take the body of the lambda, recursively replace all occurrences of the parameter
uid
with the propertyUserId
on the parameteruser
and create a new lambda expression with the transformed body and the parameteruser
.You can use an ExpressionVisitor to do the replacement.
感谢 dtb,这就是我的想法:
现在,我想,我可以使用类似于下面的代码的内容来转换谓词。我对这段代码做了一些测试;它似乎有效,但我有兴趣听到任何评论/担忧:
Thanks to dtb, here's what I came up with:
Now, I can convert the predicate, methinks, with something like the code below. I've done a wee bit of testing on this code; it seems to be working, but I'd be interested to hear any comments/concerns:
乍一看,您似乎正在构建一些 Linq 不知道如何转换为 T-SQL 的表达式。
我可能会误解您想要执行的操作,但如果您想构建 Linq To Sql 可以理解的可链式表达式,我强烈建议您查看 PredicateBuilder 扩展 此处。即使这并不完全是您想要的,了解它的工作原理也可以让您深入了解您需要在幕后实现什么才能使您正在做的事情发挥作用。
At first glance, it looks like you're building some expressions that Linq isn't going to know how to translate into T-SQL.
I might be misunderstanding what you're trying to do, but if you want to build chain-able expressions that Linq To Sql can understand, I'd highly recommend looking at the PredicateBuilder extensions here. Even if it's not exactly what you want, understanding how it works could give you some insight on what you need to achieve under the covers to make what you're doing work.