2010-04-08 110 views
1

我創建了一個LINQ擴展,就像談到here一樣。但顯然,它不適用於對孩子的查詢。LINQ兒童擴展方法

return (from p in repository.GetResources() 
       where p.ResourceNames.Any(r => r.Name.WhereIn(arg => arg.Name, "PartialWord")) 
       select p).ToList(); 

我想做到的是,ResourceNames是EntityCollection,我需要檢查,如果孩子的財產「名稱」,看看他們是否包含單詞「PartialWord」:如下面的代碼所示。

,其中適用於這樣的:

repository.GetResources().WhereIn({CODEHERE}); 

但當放置於兒童,這是行不通的。有沒有特別的方法來設置我的擴展。這是它下面:

public static class QueryableExtensions 
{ 
    private static Expression<Func<TElement, bool>> GetWhereInExpression<TElement, TValue>(Expression<Func<TElement, TValue>> propertySelector, IEnumerable<TValue> values) 
    { 
     ParameterExpression p = propertySelector.Parameters.Single(); 
     if (!values.Any()) 
      return e => false; 

     var equals = values.Select(value => (Expression)Expression.Equal(propertySelector.Body, Expression.Constant(value, typeof(TValue)))); 
     var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal)); 

     return Expression.Lambda<Func<TElement, bool>>(body, p); 
    } 

    /// <summary> 
    /// Return the element that the specified property's value is contained in the specifiec values 
    /// </summary> 
    /// <typeparam name="TElement">The type of the element.</typeparam> 
    /// <typeparam name="TValue">The type of the values.</typeparam> 
    /// <param name="source">The source.</param> 
    /// <param name="propertySelector">The property to be tested.</param> 
    /// <param name="values">The accepted values of the property.</param> 
    /// <returns>The accepted elements.</returns> 
    public static IQueryable<TElement> WhereIn<TElement, TValue>(this IQueryable<TElement> source, Expression<Func<TElement, TValue>> propertySelector, params TValue[] values) 
    { 
     return source.Where(GetWhereInExpression(propertySelector, values)); 
    } 

    /// <summary> 
    /// Return the element that the specified property's value is contained in the specifiec values 
    /// </summary> 
    /// <typeparam name="TElement">The type of the element.</typeparam> 
    /// <typeparam name="TValue">The type of the values.</typeparam> 
    /// <param name="source">The source.</param> 
    /// <param name="propertySelector">The property to be tested.</param> 
    /// <param name="values">The accepted values of the property.</param> 
    /// <returns>The accepted elements.</returns> 
    public static IQueryable<TElement> WhereIn<TElement, TValue>(this IQueryable<TElement> source, Expression<Func<TElement, TValue>> propertySelector, IEnumerable<TValue> values) 
    { 
     return source.Where(GetWhereInExpression(propertySelector, values)); 
    } 
} 

回答

2

。假定ResourceName.Name是一個字符串:

You don't need any extension for the string version of .Contains() in L2E。 (您需要僅用於L2E v.1中的列表版本)。你應該可以這樣做:

return (from p in repository.GetResources() 
     where p.ResourceNames.Any(r => r.Name.Contains("PartialWord")) 
     select p).ToList(); 
+0

你怎麼知道我使用的是什麼版本的L2E?我得到這個代碼的錯誤: LINQ to Entities無法識別方法'布爾包含(System.String,System.String,System.StringComparison)'方法,並且此方法無法轉換爲存儲表達式。 – 2010-04-08 21:55:16

+0

我不知道您使用的是哪個版本,但這並不重要,因爲'bool Contains(string)'支持在所有版本中都是相同的。但是,您試圖使用帶有StringComparison的重載,這在任何版本的L2E中都不受支持。你必須使用只帶有'string'的版本,如我的例子所示。不過,這相當於您問題中的示例代碼。 – 2010-04-08 22:03:09