我在使用ASP中继器时遇到了一些麻烦并尝试对数据进行排序。
所以在Page_Load上我获得了如下的数据源......
Protected Overloads Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not (Page.IsPostBack) Then
'No need to re-load Occasion because it's done in the PreLoad event
Me.Header.Title = "OCP - " + Occasion.Checklist.name
pnlStatistics.Visible = Not (Occasion.isClosed)
pnlClose.Visible = SecurityHelper.HasRole(SecurityMatchOption.AtLeast, SecurityRole.Manager, _relevantTeam) And Not (Occasion.isClosed)
'initially assume checklist can be closed. any un-signed off task in the item_databound event will disable it.
btnClose.Enabled = True
'Fix Issue 63: rptTask.DataSource = _db.vw_tasklists.Where(Function(o) o.occasionId = Occasion.id).ToList()
rptTask.DataSource = _db.vw_tasklists.Where(Function(o) o.occasionId = Occasion.id).OrderBy(Function(t) t.taskDueDate).ThenBy(Function(t) t.taskDueTime)
然而,在ItemDataBound中,我们重新计算任务duedate。
Private Sub rptTask_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles rptTask.ItemDataBound
' Get the data relating to this task 'row'
Dim t = CType(e.Item.DataItem, vw_tasklist)
If e.Item.ItemType = ListItemType.Header Then
Dim thDueDate = CType(e.Item.FindControl("thDueDate"), HtmlTableCell)
thDueDate.Visible = Not (Occasion.isClosed)
End If
'securable buttons
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
' Dynamically create a span element named TASKnnnn, which will be referenced from
' 'child page' links back to this page in order to vertically reposition at the selected task
Dim span = New HtmlGenericControl("span")
span.ID = "TASK" & t.taskId
span.ClientIDMode = ClientIDMode.Static ' prevent ASP.NET element ID mangling
e.Item.FindControl("lblTaskName").Parent.Controls.AddAt(0, span) ' hook it into the repeater row
Dim btnSignoff = CType(e.Item.FindControl("btnSignOff"), Button)
Dim btnComment = CType(e.Item.FindControl("btnComment"), Button)
Dim btnAmend = CType(e.Item.FindControl("btnAmend"), Button)
Dim btnView = CType(e.Item.FindControl("btnView"), Button)
Dim lblSoTime = CType(e.Item.FindControl("lblSOTime"), Label)
Dim lblDueDate = CType(e.Item.FindControl("lblDueDate"), Label)
Dim lblTaskId = CType(e.Item.FindControl("lblTaskId"), Label)
Dim lblTaskName = CType(e.Item.FindControl("lblTaskName"), Label)
lblTaskId.Text = CType(t.taskId, String)
lblTaskName.Text = t.taskName
Dim time = (If(t.taskDueTime Is Nothing, New TimeSpan(0, 23, 59, 59), TimeSpan.Parse(t.taskDueTime)))
Dim dueDateTime As DateTime = (Occasion.started.Date + time)
'Setup up due DateTime for Daily Tasks
Select Case DirectCast(t.taskDayTypeId, helpers.Constants.enDayType)
Case helpers.Constants.enDayType.Daily
lblDueDate.Text = dueDateTime.ToString("dd/MM/yyyy HH:mm")
Exit Select
Case Else
'Calculate the actual due date for non-daily tasks
Dim calculator = New Calculator()
Dim calId = t.taskCalendarId
Dim taskMonthDay = "1"
If Not t.taskMonthDayId Is Nothing Then
taskMonthDay = CType(t.taskMonthDayId, String)
End If
Dim monthDay = _db.MonthDays.First(Function(m) m.id = CInt(taskMonthDay))
Dim calendar As Model.Calendar = Nothing
If Not calId is Nothing Then
calendar = _db.Calendars.First(Function(x) calId.Value = x.id)
End If
Dim potDate = calculator.GetActualDueDate(dueDateTime, monthDay.monthDay, t, calendar)
dueDateTime = (potDate.Date + time)
lblDueDate.Text = dueDateTime.ToString("dd/MM/yyyy HH:mm")
Exit Select
End Select
因此,一旦数据显示在转发器中,则排序错误。我需要能够在到期日期重新计算之后对数据进行排序。这怎么可能?
由于
答案 0 :(得分:0)
您可以将ItemDataBound
逻辑移到原始查询中:
rptTask.DataSource = _db.vw_tasklists.
Where(Function(o) o.occasionId = Occasion.id).
Select(
Function(r)
'Fill in the logic here so the DueProperty has your real Due Date
New With {.Row = r, .DueDate = r.TaskDueDate + r.TaskDueTime}
End Function
OrderBy(Function(t) t.DueDate). ' Now we only need one OrderBy (the time is already included).
Select(Function(r) r.Row) 'But we do want to select back to the original record for the databinding
'And the ToList() was probably NEVER needed or helpful in this situation
此外,由于这看起来像linq-to-sql,我可能会稍微分解一下,所以我们将我们期望在数据库上执行的内容与我们期望在Web服务器上执行的内容完全分开:
'This runs on the databsae
Dim sqlData = _db.vw_tasklists.
Where(Function(o) o.occasionId = Occasion.id)
'This runs on the web server
rptTask.DataSource = sqlData.
Select(
Function(r)
'Fill in the logic here so the DueProperty has your real Due Date
New With {.Row = r, .DueDate = r.TaskDueDate + r.TaskDueTime}
End Function
OrderBy(Function(t) t.DueDate). ' Now we only need one OrderBy (the time is already included).
Select(Function(r) r.Row) 'But we do want to select back to the original record for the databinding
'And the ToList() was probably NEVER needed or helpful in this situation
当然,如果您开始将信息放入数据库中,您将获得最佳结果,这样您就可以在一开始就正确地对数据进行排序。