c# - EF Core LINQ Where with extension 方法未转换为 SQL
问题描述
给定以下查询:
context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) &&
r.PoNumber.ContainsOrEmpty(filter.PoNumber))
我使用这些扩展方法来保存一些代码:
public static class FilterExtensions
{
public static bool ContainsOrEmpty(this string source, string toCheck)
{
return string.IsNullOrWhiteSpace(toCheck) || source?.IndexOf(toCheck, StringComparison.OrdinalIgnoreCase) >= 0;
}
public static bool EqualsOrNull(this int source, int? toCheck)
{
return !toCheck.HasValue || source == toCheck;
}
}
问题是,由于这些扩展方法,Where 部分没有被翻译成 SQL。
我使用 .Net Core 2.2,它有这个客户端评估功能,它完全隐藏了这个问题,但 SQL 分析器还是显示了它。
有什么方法可以完成这项工作,还是我必须明确地写出 where 部分的每一部分?
解决方案
IQueryable
您可以为您的特定对象扩展。
以以下对象为例:
public class MyObject
{
public string MyProperty;
}
你可以写一个这样的扩展:
public static class MyQueryExtension
{
public static IQueryable<MyObject> WhereMyPropertyNull(this IQueryable<MyObject> queryable)
{
return queryable.Where(obj => obj.MyProperty == null);
}
}
并像这样使用它:
var queryable = new List<MyObject>().AsQueryable();
var result = queryable.WhereMyPropertyNull().ToList();
编辑
根据一些反馈,我更新了处理泛型的答案。
public static class Extensions
{
public static IQueryable<TEntity> EqualOrNull<TEntity, TProperty>(this IQueryable<TEntity> source, Func<TEntity, TProperty> selector, TProperty match)
{
return source.Where(entity => Match(selector.Invoke(entity), match));
}
private static bool Match<TEntity, TProperty>(TEntity entity, TProperty match)
{
if (entity == null) {
return true;
} else {
return entity.Equals(match);
}
}
}
它可用于将属性的值传递给 where 语句:
var list = new List<MyObject>();
list.Add(new MyObject {MyProperty = "Test"});
list.Add(new MyObject {MyProperty = "NoMatch"});
list.Add(new MyObject {MyProperty = null});
var result = list.AsQueryable()
.EqualOrNull(o => o.MyProperty, "Test")
.ToList();
推荐阅读
- c++ - C++ 贪吃蛇游戏尾虫
- javascript - 仅将 CSS 应用于与父级相同类的最内层元素
- python - NoSuchElementException:无法找到元素
- laravel - 尝试使用 laravel eloquent 在页面上获取非对象错误的属性(显示供应商电子邮件)
- javascript - 续集关联 N:M
- json - 读取 JSON 并在 VBA 中循环
- python - 为什么区域/决策边界与 sci-kit 中使用 SVM 的多类分类重叠?
- javascript - Office.js 在表格的单个列中迭代单个单元格
- java - 如何更改 Wifi P2P 设备名称?
- google-cloud-dataflow - 从 Dataflow 2.5.0 SDK 迁移到 Beam 2.13 版本