Linq для заполнения элемента управления Treeview: фильтрация в реальном времени - PullRequest
1 голос
/ 26 марта 2020

Я бы хотел обновить Treeview, когда пользователь нажимает галочку. У меня есть один Datatable с артистами / альбомами / песнями / и некоторыми другими критериями. Древовидное представление содержит 2 уровня: Исполнитель и альбомы (по 1 или несколько на исполнителя)

Итак, у меня есть оригинальный запрос linq, который выглядит следующим образом:

var query = (from i in Globals.ds.Tables[0].AsEnumerable() 
            select new { art = i.Field<string>("artiste"), alb = i.Field<string>("album"), dis = i.Field<string>("disque") })
            .Distinct()
            .GroupBy(g=> g.art)
            .OrderBy(g => g.Key);

"disque" дополнительная информация для фильтрации TreeView в зависимости от типа альбома (LP или 12 "или обоих). Затем у меня есть 2 цикла foreach, которые красиво заполняют представление дерева (запрос не показывает песни, что здорово, если иметь количество альбомов на артиста). )

Я бы хотел обновить запрос "вживую", когда пользователь нажимает на поля (LP, 12 "или оба), поэтому у меня есть следующее (у меня тот же linq для 12"):

  if (!LP.Checked)
        {
            query = query.Where(p => (string)p.dis != "LP") ;
        }

Но "p.dis" недоступен, у меня есть только "p.key", который является артистом.

Как я могу использовать .where на этом шаге ? Спасибо

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Без использования Dicionary:

Если вам нужно отфильтровать все artist, у которых нет disque звонков LP, измените немного свой код:

1 - изменить orderBy и GroupBy для возврата IEnumerable<IGrouping<>> вместо IOrderedEnumerable<IGrouping<>>

var query = (from i in Globals.ds.Tables[0].AsEnumerable() 
    select new { art = i.Field<string>("artiste"), alb = i.Field<string>("album"), dis = i.Field<string>("disque") })
    .Distinct()
    .OrderBy(g => g.Key)
    .GroupBy(g=> g.art);

2 - во втором запросе использовать функцию where:

if (!LP.Checked)
{
    query = query.Where(x => !x.Any(p => p.dis == "LP"));
}

Использование Dicionary:

Если вы хотите фильтровать внутри сгруппированных значений, вы можете использовать Dictionary<> вместо IEnumerable<IGrouping>, возвращаемого функцией GroupBy, например следующий код:

1 - в первом запросе используйте ToDictionary для преобразования IEnumerable<IGrouping> в Dictionary<>

var query = (from i in Globals.ds.Tables[0].AsEnumerable() 
    select new { art = i.Field<string>("artiste"), alb = i.Field<string>("album"), dis = i.Field<string>("disque") })
    .Distinct()
    .GroupBy(g=> g.art)
    .OrderBy(g => g.Key)
    .ToDictionary(x => x.Key, y => y.ToList());

2 - используйте простой Where внутри ToDictionary для фильтрации значений для каждой artist группы, например, следующий код:

if (!LP.Checked)
{
    query = query.ToDictionary(x => x.Key, y => y.Value.Where(p => p.dis != "LP").ToList());
}

Второй запрос отфильтрует внутренние значения.

Документация:

словарь

todictionary

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

1 голос
/ 26 марта 2020

Попробуйте и посмотрите на эту простую демонстрацию. Возможно, это поможет вам достичь того, чего вы хотите:

void Main()
{
    var data = new List<Data>
    {
        new Data { Art = "Art1", Alb = "Alb1", Dis = "LP"},
        new Data { Art = "Art1", Alb = "Alb2", Dis = "12"},
        new Data { Art = "Art2", Alb = "Alb1", Dis = "LP"},
        new Data { Art = "Art3", Alb = "Alb1", Dis = "LP"}
    }; 

    var query = 
        (from i in data
        select new Data { Art = i.Art, Alb = i.Alb, Dis = i.Dis })
        .Where(WhereFunc())
        .Distinct()
        .GroupBy(g => g.Art)
        .OrderBy(g => g.Key);
}

static Func<Data, bool> WhereFunc() => (p) =>
{                
    if (!LP.Checked)
    {
        return (string)p.Dis != "LP";
    }
    else
    {
        return (string)p.Dis == "LP";
    }
};

public class Data
{
    public string Art {get; set;}
    public string Alb {get; set;}
    public string Dis {get; set;}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...