将标准linq查询转换为通用实现

时间:2013-03-08 21:35:32

标签: c# linq

我有以下代码和linq查询:

class Program
{
    static void Main(string[] args)
    {
        var allProfessionals = new Collection<Professional>
         {
             new Professional { Name = "Bruno Paulovich Silva" },
             new Professional { Name = "Ivan Silva Paulovich Bruno"},
             new Professional { Name = "Camila Campos"}
         };

        var namesSearch = new[] {"bruno", "silva"};

        var query = namesSearch.Aggregate(allProfessionals.AsQueryable(), (current, nome) => current.Where(oh => oh.Name.ToLower().Contains(nome.ToLower())));

        foreach (var res in query.ToList())
        {
            Console.WriteLine(res.Name.ToLower());
        }
    }
}

结果是:

Bruno Paulovich Silva
Silva Paulovich Bruno

我想知道如何将linq查询聚合转换为可以在其他时间重用的泛型方法。

在下面的示例中,我展示了我对项目中使用的通用查询的理解:

public IQueryable<T> QueryBy(Expression<Func<T, bool>> criteria)
{
    return DbSet.Where(criteria);
}

ps:抱歉我的英文不好

2 个答案:

答案 0 :(得分:2)

坚持基本要素和与脚本相同的输出,它将类似于:

class Program
{
    static void Main(string[] args)
    {
        var allProfessionals =
            new Collection<Professional>
                {
                    new Professional {Name = "Bruno Paulovich Silva"},
                    new Professional {Name = "Ivan Silva Paulovich Bruno"},
                    new Professional {Name = "Camila Campos"}
                };

        var namesSearch = new[] {"bruno", "silva"};

        var items = allProfessionals
            .Select(x => x.Name)
            .ContainsAll(namesSearch);

        foreach (var res in items)
        {
            Console.WriteLine(res);
        }
    }
}

static class Extensions
{
    public static IEnumerable<string> ContainsAll(this IEnumerable<string> haystacks, IEnumerable<string> needles)
    {
        var lowerNeedles = needles.Select(x => x.ToLower()).ToList();
        var lowerHay = haystacks.Select(x => x.ToLower()).ToList();

        // note that Regex may be faster than .Contains with larger haystacks
        return lowerNeedles
            .Where(hay => lowerHay.All(hay.Contains)); // or .Any(), depending on your requirements
    }
}

请注意,如果使用LinqToSQL或类似技术,则可能无法使用表索引。这可能会使查询变得非常慢。

为了使其与上述QueryBy<T>相符,它可能看起来像:

        var items = allProfessionals.QueryBy(
            professional => namesSearch
                .Select(needle => needle.ToLower()) // convert all to lower case
                .All(hay => professional.Name.ToLower().Contains(hay))); // then try to search for a professional that matches all nameSearch.

答案 1 :(得分:0)

这是我如何为LikeBy实现一个方法,其中一个字符串数组相当于一个包含all的方法。

public IQueryable<T> LikeBy(string[] strings, Func<IQueryable<T>, string, IQueryable<T>> criteria)
{
    return strings.Aggregate(GetAll(), criteria);
}

这里是如何实现的例子:

public IQueryable<ViaturaFuncao> FindByNome(string names)
{
    return Uow.Professional.LikeBy(names.Trim().Split(' '),
                                       (professional, nameProfessional) =>
                                       professional.Where(
                                           f => f.Name.ToLower().Contains(nameProfessional.ToLower())));
}

PS:在项目中我们使用UnitOfWork,这就是为什么在实体之前有UOW