是否可以将LINQ查询的一部分放在函数中?
基本上,我有一个数据库查询,其中包含许多内容,其中我想在函数中创建这些内容。我只是不能让它工作。非常简单的示例:
// _context is the DatabaseContext
var tmp = _context.Person.Where(p => p.Surname.Contains("Ai"));
tmp = tmp.Where(p => SomeFunction(p));
var res = tmp.ToList();
函数看起来像这样:
private bool SomeFunction(Person p)
{
return p.IsFemale;
}
这会引发异常:
The LINQ expression 'DbSet<Person>
.Where(p => p.Surname.Contains("Ai"))
.Where(p => MyController.SomeFunction(p))' could not be translated. Either rewrite
the query in a form that can be translated, or switch to client evaluation explicitly by
inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
是的,当我调用'tmp.tolist()'首先调用'tmp.tolist()',但随后将其内存过滤,我想要的是扩展查询在数据库上。
这可能吗?如果是的话,怎么办?
Basically, I have a Database query with a lot of stuff in a WHERE clause, which I want to create in a function. I just cant get it to work. Very simple example:
// _context is the DatabaseContext
var tmp = _context.Person.Where(p => p.Surname.Contains("Ai"));
tmp = tmp.Where(p => SomeFunction(p));
var res = tmp.ToList();
and the function looks like this:
private bool SomeFunction(Person p)
{
return p.IsFemale;
}
And this throws an exception:
The LINQ expression 'DbSet<Person>
.Where(p => p.Surname.Contains("Ai"))
.Where(p => MyController.SomeFunction(p))' could not be translated. Either rewrite
the query in a form that can be translated, or switch to client evaluation explicitly by
inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Yes, it works when I call 'tmp.ToList()' first but then it will be filtered in-memory, what I want is to extend the query on the database.
Is this possible? How can it be done, if so?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以构建一个表达式并传递:
buildFilter
方法将使您的lambda转换为表达树。然后,您可以这样使用它:如果您想这样做,就有一种更复杂的方法来构建表达式:
但是我认为在这种情况下,第一种方法更容易阅读和理解。
You could build an expression and pass that:
The
BuildFilter
method will transform your lambda into an expression tree. You could then use it like this:There is a more complicated way to build the expression if you wish to go that way:
But I think in this case, the first approach is much easier to read and understand.
EF与表达式树一起使用以创建查询,并且无法将方法调用转换为某些SQL,该SQL将在DB中执行(不在内存中)。
您可以将方法重写为此:
然后:
另一种方法 - 您可以创建扩展方法:
现在您可以使用方法链:
The EF works with Expression trees to create queries and it can't translate method call to some SQL which will be executed in DB (not in memory).
You can rewrite your method to this:
and then:
Another approach - you can create extension method:
and now you can use method chaining: