[英]Entity Framwork Core Lambda Function not early terminating
我正在使用带有实体框架的 asp.net 内核。
在进行 API 调用以获取实体列表时,我在 json 中传递了一个可选过滤器,该过滤器可能如下所示:
{
"name": "john",
"customer.id": 1
}
在我的 ControllerAction 中,我首先反序列化 JSON,然后查询数据库。
var dynamicfilter = filter != null ? JsonConvert.DeserializeObject<Dictionary<string, string>>(filter) : new Dictionary<string, string>();
List<User> Users = _context.Users.Include(u => u.Customer).Where(u =>
dynamicfilter.Keys.Count > 0 ? (
(dynamicfilter.ContainsKey("name") ? u.Name.ToLower().Contains(dynamicfilter["name"].ToLower()) : true) &&
(dynamicfilter.ContainsKey("customer.id") ? u.Customer.ID == Convert.ToInt32(dynamicfilter["customer.id"]) : true)
) : true).ToList();
只要设置了所有过滤器参数,它就可以工作。 如果未设置至少一个过滤器参数,则会抛出 null 引用,因为即使ContainsKey()
为false
,代码之间的代码是什么? 和:被执行。
但是如果我首先加载整个表并在本地应用过滤器,通过这样做
List<User> Users = _context.Users.Include(u => u.Customer).ToList().Where(...
它就像一个魅力。 有没有办法让它在数据库端也能工作?
只需将逻辑移出查询即可。 喜欢:
IQueryable<User> query = _context.Users.Include(u => u.Customer);
query = dynamicfilter.ContainsKey("name")
? query.Where(u=>u.Name.ToLower().Contains(dynamicfilter["name"].ToLower())
: query;
query = dynamicfilter.ContainsKey("customer.id")
? query.Where(u=>u.Customer.ID == Convert.ToInt32(dynamicfilter["customer.id"]))
: query;
List<User> Users = query.ToList(); // DB query executed here
这样,表达式树将在query
object 中构建,并且仅在尝试枚举时执行。 检查 MS 文档
此接口继承了 IEnumerable 接口,因此如果它表示一个查询,则可以枚举该查询的结果。 枚举强制执行与 IQueryable object 关联的表达式树。 调用 Execute(Expression) 方法时会执行不返回可枚举结果的查询。
最重要的是,我建议在将其应用于查询之前检查所有传入参数
if(dynamicfilter.ContainsKey("name")
&& !string.IsNullOrWhitespace(dynamicfilter["name"]))
{
var nameFilter = dynamicfilter["name"].ToLower();
query = query.Where(u=>u.Name.ToLower().Contains(nameFilter);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.