[英]EF Core LINQ Where with extension mehods are not translated to SQL
Given the following query:鉴于以下查询:
context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) &&
r.PoNumber.ContainsOrEmpty(filter.PoNumber))
I use these extension methods to save some code:我使用这些扩展方法来保存一些代码:
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;
}
}
The problem is, due to these extension methods, the Where part is not translated into SQL.问题是,由于这些扩展方法,Where 部分没有被翻译成 SQL。
I use .Net Core 2.2, wich has this client side evaluation feature , which totally hides this issue, but the SQL profiler shows it anyway.我使用 .Net Core 2.2,它有这个客户端评估功能,它完全隐藏了这个问题,但 SQL 分析器无论如何都会显示它。
Is there any way to make this work, or I have to write every piece of the where part explicitly?有什么办法可以使这项工作,或者我必须明确地写下 where 部分的每一部分?
You could extend the IQueryable
for your specific object.您可以为您的特定对象扩展IQueryable
。
Take the following object for instance:以以下对象为例:
public class MyObject
{
public string MyProperty;
}
You could write an extension like this:你可以写一个这样的扩展:
public static class MyQueryExtension
{
public static IQueryable<MyObject> WhereMyPropertyNull(this IQueryable<MyObject> queryable)
{
return queryable.Where(obj => obj.MyProperty == null);
}
}
And use it like this:并像这样使用它:
var queryable = new List<MyObject>().AsQueryable();
var result = queryable.WhereMyPropertyNull().ToList();
EDIT编辑
Based on some feedback i updated my answer to handle generics.根据一些反馈,我更新了我的答案来处理泛型。
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);
}
}
}
It can be used to pass the value of a property to the where statement:它可用于将属性的值传递给 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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.