关于子的LINQ扩展方法

时间:2010-04-08 21:23:08

标签: linq-to-entities

我在谈到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,我需要检查子项的属性“Name”是否包含“PartialWord”这个词。

WhereIn就像这样:

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));
    } 
}

1 个答案:

答案 0 :(得分: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();