c# - 编译的 C# Linq 表达式> 并查询 Mongo
问题描述
我从一位前雇员那里继承了一些代码,该代码使用编译的 Linq 表达式和MongoRepository 库(位于 MongoDB C# 驱动程序之上)查询 mongo DB。
这些需要很长时间才能运行 - 通常大约 6 分钟(!)并导致使用它们的控制器方法出现问题。
所以我简化了代码并删除了.Compile()
对 lambda 表达式的调用,这似乎解决了这个问题(现在运行需要 <10 秒)。
我的问题是:为什么在查询 mongo 时编译这个表达式会导致问题?
这是原始代码的要点(被黑了,所以断章取义):
public class BaseMongoRepository<T> : MongoRepository<T, Guid> where T : IEntity<Guid> {
protected BaseMongoRepository(string connectionString) : base(connectionString) { }
protected bool IsSatisfiedBy(T entity) {
Expression<Func<T, bool>> func = x => x != null && x.ToString() == "foo"; // query was passed in, but you get the idea
var predicate = func.Compile(); // THIS LINE??
return predicate(entity);
}
public IEnumerable<T> Find() {
return base.collection.AsQueryable().Where(IsSatisfiedBy);
}
}
我将它简化为只使用常规谓词的东西Func
:
public IEnumerable<T> Find() {
return base.collection.AsQueryable().Where(x => x != null && x.ToString() == "foo");
}
任何想法都非常感谢!
解决方案
提供者可以将表达式转换为真正的 sql 查询,但不能解释委托。
此代码中的predicate
变量:
Expression<Func<T, bool>> func = x => x != null && x.ToString() == "foo";
var predicate = func.Compile();
本质上是一样的:
Func<T, bool> predicate = x => x != null && x.ToString() == "foo";
当您使用这样的委托时,数据库中的所有数据都将传输到内存中,然后应用谓词。
伪代码示例:
// Using the delegate:
var data = dbContext.Users.Where(usr => IsSatisfiedBy(usr)).ToList();
// This will result in the following steps:
var userList = ExecuteQuery("SELECT * FROM Users"); // all users are fetched.
var satisfied = userList.Where(usr => IsSatisfiedBy(usr))
// Using an expression:
var data = dbContext.Users.Where(usr => usr.Name == "foo");
// This will result in the following step:
var satisfied = ExecuteQuery("SELECT * FROM Users WHERE Name = 'foo'"); // Filtered before returned to caller.
推荐阅读
- firebase - Firebase 安全规则检查多个引用
- javascript - How to parse an array inside EJS template
- .net - 从支付网关回发时丢失会话
- sql - 如何检查具有特定条件的行或仅检查引用是否为空或不存在?
- javascript - 服务器/客户端之间的 Nest.js socket.io ping/pong
- gradle - 我如何将依赖 jar 和 POM 发布到新的存储库?
- python - 访问和替换 json 中的子类别对象
- c++ - 如何使用 Visual Studio 正确链接 libcurl?
- amazon-web-services - AWS DMS:如何处理 Presto/Athena 中的 TIMESTAMP_MICROS parquet 字段
- python - 如何在aws s3中找到指定日期内的学生人数?