在没有自定义类型的绑定字段上显示连接值?

时间:2009-01-12 16:01:50

标签: c# asp.net linq

我有一个绑定到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();
}

很抱歉,如果这个解释不是很明确!

3 个答案:

答案 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>