2017-07-17 114 views
2

例如, 「IN」:自定義擴展,功能實現在C#(LINQ-2-實體)

。載有(...)的supporten在Linq2Entities並轉化爲 「IN」 的SQL表達式。

我婉重寫此查詢:

var foundExntities = myDbContext.MyEntityes.Where(o => new List<int> {111, 222, 333).Contains(o.ID)).ToList() 

在形式上像有:

var foundExntities = myDbContext.MyEntityes.Where(o => o.ID.In(111, 222, 33)).ToList() 

我怎麼能寫correspondend定製在(...)分機功能?

+3

我建議你不要。在'int'上定義擴展方法是非常令人困惑的,當這些方法泄漏到不能使用的上下文中(並且寫入它們以便它們可以在任何地方使用似乎都不值得)。除此之外,我不認爲你可以* - 方法需要被EF表達式樹解析器識別,我不認爲它們有擴展點。 (雖然我對EF本身並不熟悉,但我確信你可以包裝'IQueryable'實現,但即使這樣做似乎比它的價值更麻煩。 –

+0

儘管可以使用'params int []'聲明可變數量的整數參數(請參閱https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/how-to -add-custom-methods-for-linq-queries),我反對在EF中創建自定義聚合方法。由於自定義方法有時不直接轉換爲SQL查詢,因此可能會引發諸如「LINQ to Entities does not recognized the method」之類的問題。 –

+0

我只想提取**以EF(LINQ-2-SQL)表達式**爲這種宏函數而聞名。這個函數只會擴展我的查詢樹。 –

回答

3

我該如何編寫通信和自定義在(...)擴展函數中?

你不能沒有也寫它通過識別您的自定義擴展方法,並相應地轉換他們(類似LINQKitAsExpandable()實現)的表達式樹轉換一個完全成熟的查詢提供。

你能雖然做的是創建一個自定義IQueryable<T>擴展方法與限制,它只能與LINQ方法語法和只用根可查詢的運營商所使用的:這是適用於你的樣品

public static partial class QueryableExtensions 
{ 
    public static IQueryable<T> WhereIn<T, V>(this IQueryable<T> source, Expression<Func<T, V>> valueSelector, params V[] values) 
    { 
     var condition = Expression.Call(
      typeof(Enumerable), "Contains", new[] { typeof(V) }, 
      Expression.Constant(values), valueSelector.Body); 
     var predicate = Expression.Lambda<Func<T, bool>>(condition, valueSelector.Parameters); 
     return source.Where(predicate); 
    } 
} 

作爲:

var foundEntities = myDbContext.MyEntityes.WhereIn(o => o.ID, 111, 222, 33).ToList(); 
+0

感謝很多伊凡! –