簡體   English   中英

EF Core LINQ Where 擴展方法未轉換為 SQL

[英]EF Core LINQ Where with extension mehods are not translated to 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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM