在我的c#WPF应用程序中,我在运行时向DataGrid添加列,并通过LINQ从我的SQL数据库填充。这是正常工作,直到我尝试从我的多对多表中添加数据
这是我的db:
的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;
我正在获取关键字标题,但这些单元格都是空白的。绑定在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 :(得分: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();