Criando um filtro dinâmico Linq sobre List
-
05-07-2019 - |
Pergunta
Ok, eu fiz esta pergunta antes, mas excluí-la como a maneira que eu fui sobre descrever o meu problema estava errado.
Em primeiro lugar, deixe-me dizer que eu estou criando um aplicativo NET3.5 WinForms usando C # e Plinqo (Professional Linq to Objects) como meu ORM. Aqui está a minha situação: Eu tenho um datagridview que é preenchida a partir de um SortableBindingList<T>
- no meu caso, formado a partir de um List<Task>
que é simplesmente representados da seguinte forma:
public class Task {
public long TaskID { get; set; }
public string TaskDescription { get; set; }
public enumPriority TaskPriority { get; set; }
public DateTime DueDate { get; set; }
public double PercentageComplete { get; set; }
}
Agora, eu quero dar uma janela para o meu usuário para permitir que ele / ela para filtrar essa lista. Prevejo passar em uma lista de nomes de propriedades e tipo de dado associado ao diálogo que eu possa usar para preencher uma caixa de combinação. Assim, o usuário vai escolher qual propriedade que deseja consultar a partir da caixa de combinação e com base na seleção os comparadores apropriadas e controle de UI serão disponibilizados para o usuário para entrar em vários daqueles critérios. Por fim, ele conterá um E / OU togglebutton no final do qual o usuário pode usar para adicionar critério adicional. Cada critério será um objecto do tipo FilterItem
como mostrado abaixo:
public class FilterItem {
public string MappedPropertyName { get; set; }
public enumComparer Comparer { get; set; }
public object FilterValue { get; set; }
public enumOpertor Operator { get; set; }
}
Depois que o usuário constrói seu / sua consulta, pretendo passar este como um back List<FilterItem>
a minha forma de chamar, que pode então iterar através da lista e permitir-me para filtrar a List<Task>
originais.
Esta é tudo muito bem, e algo que eu possa montar com facilidade. Mas eu quero ter certeza de que o mecanismo de filtro real eu ir com é tão fortemente tipado possível, e não usando bulit-se strings como na Biblioteca de Consulta Dinâmico. (Eu costumava fazer algo semelhante anteriormente com ADO.NET, DataViews e dinamicamente construir uma string RowFilter)
Eu ler sobre Joseph Albahari do PredicatBuilder e um artigo sobre tomasp.net , mas me parece muito confuso com isso e árvores de expressão em geral.
Eu sinceramente buscam seu auxílio em ajudar-me a compreender melhor estes conceitos, e como fazer para usá-lo de modo que minha arquitetura destina pode trabalhar com ele.
Muita apreciação!
Solução
Além disso, eu sei que posso fazer algo como:
private SortableBindingList<Task> GetSortedTaskList()
{
List<Task> list = new List<Task>();
var query = DataUtil.GetUserTasks(xSys.Current.UserID);
if (/*description condition met*/)
{
query = query.Where(x => x.TaskDescription.Contains(FilterDesc));
}
if (/*due date condition met*/)
{
query = query.Where(x => x.DueDate >= FilterDate);
}
if (/*priority condition met*/)
{
query = query.Where(x => x.TaskPriority == FilterPriority);
}
...
list = query.ToList();
return new SortableBindingList<ArcTask>(list);
}
mas isso não parece muito escalável e 'dinâmico'.