我有一个绑定到ICollection<UserAnswer>
的GridView需要显示两列:
<asp:GridView ID="UserAnswersGridView" runat="server">
<Columns>
<asp:BoundField DataField="Question.Name" HeaderText="Question Name" SortExpression="QuestionID" />
<asp:BoundField DataField="Score" HeaderText="Score" SortExpression="Score" />
</Columns>
</asp:GridView>
但我收到错误:
在所选数据源上找不到名为“Question.Name”的字段或属性。
每个UserAnswer
都有QuestionId
值,这是我用来查询问题名称的值。在代码中,我只会调用userAssessment.Question.Name
,但是如何在GridView中使用绑定列而不创建新类型?
作为参考,这是返回数据的方法:
public static ICollection<UserAnswer> GetUserAnswers(Int32 userAssessmentId)
{
DataContext database = new DataContext(GetConnectionString());
return database.UserAnswers.Where(u => u.UserAssessmentId == userAssessmentId).ToList();
}
很抱歉,如果这个解释不是很明确!
答案 0 :(得分:2)
我相信GridView
仅支持直接类型的属性。转发器或任何类似的选项?这为您提供了更大的灵活性。
或者,您可以通过部分类向该类型添加填充属性:
namespace YourLinqNamespace {
partial class UserAnswer {
public string QuestionName {get {return Question.Name;}}
}
}
您不能在过滤器(Where
等)中使用它,但您应该能够在返回的对象上使用它而不会出现问题。请注意,您可能希望使用LoadWith
来保存往返次数:
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<UserAnswer>(x=>x.Question);
database.LoadOptions = options;
答案 1 :(得分:1)
您还可以使用ItemDataBoundEvent在代码后面设置字段。或者您可以使用匿名类型,这有点像Marc的垫片属性概念,但您不会修改您的域模型。
from u in database.UserAnswers
Where u.UserAssessmentId == userAssessmentId
select new { QuestionName=u.Question.Name,
Answer = u.Answer
//etc etc
};
正如Marc指出你不应该从方法中返回Anonymous类型,我在手动绑定到数据源时使用了技巧,所以:
myGrid.DataSource = from u etc ....
在我看来,使用我的第一个建议更好,并在项目数据绑定事件中处理它。
答案 2 :(得分:1)
与Marc Gravell一样,我几乎总是会为这些案例创建垫片属性。另一个选择是使用模板列而不是绑定列,但它实际上取决于您的情况:
<asp:TemplateField HeaderText="Question Name">
<ItemTemplate>
<%# Eval("Question.Name") %>
</ItemTemplate>
</asp:TemplateField>