2011-02-04 11 views
0

私のC#WPFアプリケーションでは、実行時にDataGridに列を追加し、LINQを使用してSQLデータベースからデータを取り込みます。私は私の多対多のテーブルからWPFデータバインディングパスのLINQ多対多

をデータを追加しようとするまで、これが正常に動作して、ここで3つの関連するテーブルの私のデシベルの簡易版です:私は私のDataGridに何をしたい

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

列です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への私の最初の挑戦であるので、私を許してください。

答えて

0

私はあなたのコードを書き直そうとしましたが、それは簡単な作業ではありませんし、動作しているかわかりません。 documents_keywords.FirstOrDefault(の代わりに配列Keywords["+i+"]"の順次インデックスに各列のバインディングを設定し、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