我设计了一个用户控件来向用户显示问题列表。这个“问题列表”控件只包含一个转发器。有多种类型的问题和表单字段必须用于回答问题,因此它们被实现为一系列“问题输入”控件,这些控件动态加载到 ItemTemplate 中。每个问题输入控件都包含一个按钮,用于提交该问题的答案。提交的答案通常会更改问题列表,因此在提交任何答案并保存到数据库后,我希望问题列表能够重新生成。
以上都正常工作,除了在提交答案后反弹问题列表时,新列表包含重复的行并且还缺少一行,如下所示:
原名单:
Q1
Q2 <---- Save button clicked on this question
Q3
Q4
新列表(第二季度重复和第四季度缺失):
Q1
Q2
Q2
Q3
我在动态加载的问题输入控件上获得答案提交以重新绑定问题列表的方式是这样的:
在问题列表控件的 Page_Load 中,如果 Page.IsPostBack 为 true,我将调用 Repeater.DataBind()。这将重新创建问题输入控件并触发其按钮单击事件。第一个挑战是这些事件在父控件的 Page_Load 完成后触发,但我找到了一种在父控件上创建“ForceReload”属性的方法,问题输入控件可以在其按钮单击事件中设置为 True。因此,在问题列表控件的 Page_PreRender 中,我检查 ForceReload=true 是否,如果是,则再次调用 Repeater.DataBind()。
正是在第二个数据绑定中发生了奇怪的事情。如果我单步执行代码,我可以看到与提交的问题相对应的 DataItem 出现了两次。但是,第二次运行的 SQL 查询与第一次运行的 SQL 查询相同,并且返回的记录相同(即第二次的结果中没有重复)。
我想我需要在第二次数据绑定之前做某种中继器“重置”,但看不到任何功能。
可能的原因....问题的唯一键在第一个数据绑定和第二个数据绑定之间发生变化。我知道这听起来很奇怪,但这就是数据库的工作方式——一个 qiven 问题在其“未回答”状态下可能有一个唯一 ID“-123”,然后在其“已回答”状态下有一个“123”。如果我强制 ID 保持不变,则不会出现问题。更改 ID 与数据源是视图而不是表这一事实有关,无论如何我对此无能为力。当中继器不知道唯一 ID 是什么时,它为什么还要关心?
更新:经过更多测试,它肯定是 LINQ 问题,而不是中继器或 SQL 问题。这是一个简单的例子:
第一次绑定时检索到的数据:
QuestionID QuestionNumber Answer
---------- -------------- ------
-1 1 null
-2 2 null
-3 3 null
-4 4 null
然后提交问题#2,并列出反弹。第二次绑定检索到的数据:
QuestionID QuestionNumber Answer
---------- -------------- ------
-1 1 null
2 2 My answer
-3 3 null
-4 4 null
所以数据是完全正确的。然而,这被 LINQ 转换为具有以下属性的 4 个对象:
QuestionID QuestionNumber Answer
---------- -------------- ------
-1 (OK) 1 (OK) null (OK)
2 (OK) 2 (OK) My answer (OK)
-3 (OK) 2 (wrong) My answer (wrong)
-4 (OK) 3 (wrong) null (OK)
因此,在每个对象中,关键属性 (QuestionID) 是正确的,但是在问题更新后的对象中,其他属性是从先前的记录中提取的!