LINQ многие ко многим в пути привязки данных WPF - PullRequest
0 голосов
/ 05 февраля 2011

в моем приложении c # WPF я добавляю столбцы в DataGrid во время выполнения и заполняю из своей базы данных SQL через LINQ. это работает нормально, пока я не попытаюсь добавить данные из моей таблицы «многие ко многим»

вот упрощенная версия 3 соответствующих таблиц my db:

documents: document_id, title
documents_keywords: document_id, keyword_id, value
keywords: keyword_id, name

что мне нужно в моей DataGrid - это столбец для document.title, плюс столбец для каждой записи в document.documents_keywords на основе выбора пользователя вот мой код:

        DataGrid dataGrid = new DataGrid();
        dataGrid.Columns.Add(new DataGridTextColumn
        {
            Header = "Title",
            Binding = new Binding("title")
        });
        foreach (string keywordName in keywordsListBox.SelectedItems)
        {
            dataGrid.Columns.Add(new DataGridTextColumn
            {
                Header = keywordName,
                Binding = new Binding("documents_keywords.FirstOrDefault(kw => kw.keyword.name.Equals(\""+keywordName+"\")).value")
            });
        }

        dataGrid.ItemsSource = from d in db.documents select d;

Я получаю заголовки ключевых слов, но все ячейки пустые. сбой привязки при FirstOrDefault:

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstOrDefault(d_k => d_k.keyword.name.Equals("Order#"))' property not found on 'object' ''EntityCollection`1' (HashCode=7935090)'. BindingExpression:Path=documents_keywords.FirstOrDefault(d_k => d_k.keyword.name.Equals("Order#")).value; DataItem='document' (HashCode=5781744); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

каков наилучший способ сделать это? прости меня, так как это моя первая прогулка по WPF и LINQ.

1 Ответ

0 голосов
/ 05 февраля 2011

Я пытался переписать ваш код, но это не простая задача, и я не уверен, работает ли он. Я установил привязку каждого столбца к последовательному индексу массива Keywords["+i+"]" вместо documents_keywords.FirstOrDefault( и изменил структуру ItemSource.

У меня нет возможности самостоятельно проверить этот код, поэтому, если у вас возникнут проблемы - напишите их в разделе комментариев.

    DataGrid dataGrid = new DataGrid();
    dataGrid.Columns.Add(new DataGridTextColumn
    {
        Header = "Title",
        Binding = new Binding("title")
    });
    //all possible keywords
    var items = db.keywords.Select(k => new {Id = k.keyword_id, Name = k.name}).ToArray();
    //selected keywords ordered by id
    var selected = (from item in items
                   where keywordsListBox.SelectedItems.Contains(item.Name)
                   orderby item.Id
                   select item)
                   .ToArray();
    //create columns and bind them
    for(int i = 0; i < selected.Length; i++)
    {
        dataGrid.Columns.Add(new DataGridTextColumn
        {
            Header = selected[i].Name,
            Binding = new Binding("Keywords["+i+"]")
        });
    }

    var documents = (from d in db.documents
                     select new{ 
                        d.title, 
                        //All related keywords
                        Keywords = d.documents_keywords.Select(dk => 
                                       new { Id = dk.keywoard_id, Value = dk.value})
                                      .ToList()}) 
                    .AsEnumerable()
                    .Select(doc => new {
                        title = doc.title,
                        //Only selected keywords with default null values
                        Keywords = (from si in selected
                                   join k in doc.Keywords on si.Id equals k.Id into j
                                   from ji in j.DefaultIfEmpty(new { Id = si.Id, Value = null})
                                   orderby ji.Id
                                   select ji.Value)
                                   .ToArray()
                        });
   dataGrid.ItemsSource = documents.ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...