Цикл по параметрам для генерации LINQ во время выполнения - PullRequest
1 голос
/ 22 июля 2011
public class Command
{
    public int CommandId { get; set; }
    public string Title { get; set; }
    public virtual ICollection<CommandPart> CommandParts { get; set; }
}

public class CommandPart
{
    public int CommandPartID { get; set; }
    public string part { get; set; }
    public virtual ICollection<Command> command { get; set; }
}

public ViewResult Filter(string myString)
{
    var foo = myString.Split(Convert.ToChar("+"));
    var a = foo[0];
    var b = foo[1];

    var query =
    db.Commands.Where(
        c =>
        c.CommandParts.Any(p => p.part == a) 
        && (c.CommandParts.Any(p2 => p2.part == b))).ToList();

    return View(query.ToList());
}

Запрос выше работает, как и ожидалось, когда в foo ровно два элемента.Я хотел бы иметь возможность перебрать foo для создания запроса.Вот моя попытка, но она не работает:

        var foo = myString.Split(Convert.ToChar("+"));
        IQueryable<Command> query = db.Commands;

        foreach (var keyword in foo)
        {
            query = query.Where(c => c.CommandParts.Any(p => p.part == keyword));
        }

Это проект ASP.NET MVC3, использующий Entity Framework.Как я могу написать запрос, чтобы он генерировался во время выполнения?

1 Ответ

3 голосов
/ 22 июля 2011

Посмотрите на PredicateBuilder .Это небольшой вспомогательный класс, который инкапсулирует некоторые выражения LINQ, которые позволяют динамически создавать предложение предиката Where.Вы можете объединять предложения И и ИЛИ и вкладывать их довольно глубоко.

Таким образом, вы можете сделать что-то вроде этого (псевдокод):

var predicate = PredicateBuilder.True<Command>(); //use True for ANDs
foreach(var keyword in foo) {
  predicate = predicate.And(c => c.CommandParts.Any(p => p.part==keyword));
}
var results = db.Commands.Where(predicate);

Я пропустил, что вы используете EF, поэтому вам нужно скачать LINQKit (NuGet, который вы также можете скачать) и использовать его расширение «AsExandable».См. Страницу PredicateBuilder об этом (примерно на полпути).

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...