2011-02-04 63 views
0

我的c#WPF应用程序我在运行时将列添加到DataGrid中,并通过LINQ从我的SQL db中填充。这是工作的罚款,直到我试图从添加数据我许多一对多表LINQ多对多WPF数据绑定路径

这里的3个相关表格的简化版本,我的数据库:

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; 

我得到的关键字标题,但单元格都是空白的。在FirstOr默认绑定失败:

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。

回答

0

我试着重写你的代码,但这不是一件容易的事,我不确定它是否有效。 我已将每列的绑定设置为数组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(); 
+0

对于迟到的反应感到遗憾 - 这个项目远远没有列入优先事项清单,我只是回到它。你的解决方案错误在最后一行,但考虑到复杂性,我想我会尝试一种不同的方法。谢谢! – codeManJones 2011-03-22 19:06:28