如何改进自定义的渲染';数据日历';在asp.net中
本文关键字:日历 asp net 数据 何改进 自定义 | 更新日期: 2023-09-27 18:19:58
我被要求改进ASP.Net C#页面。它目前显示了一种产品一年的每日价格。该页面看起来类似于墙规划师,每个输入控件都显示当天的价格。
该页面将用于更改该产品当年的价格。目前,"墙规划器"表控件正在代码后面的单元格中逐单元格生成。
有很多代码用于实现这一点,但本质上它做到了以下几点。
建立了一个表。。。动态
- 已定义新表控件
- 定义了12个新的TableRow控件(月)
- 每行添加了31个TableCell控件(每个控件都有一个唯一的id,例如cell_yy_mm_dd)
它充满了数据
- 从数据库中检索365天的价格(价格和日期)
- Foreach用于在数据集上循环
- 使用TableCells id检查的日期。如果匹配,则向单元格中添加一个新的TextBox
这给服务器带来了巨大的压力(特别是内存使用)。它似乎设计过度了,一定有更好的方法!
实现这种功能的更好方法是什么?
这就是我解决问题的方法。使用两个中继器,一个用于月,一个为天。使用当前日历,我可以使用linq从代码中生成月份和日期,并在日期上与数据库中的值左联接
代码
//The values from the DB
var values = new List<DateValue>()
{
new DateValue(){ Date = new DateTime(2012, 1, 12), Value = 5000 },
new DateValue(){ Date = new DateTime(2012, 11, 15), Value = 3000 }
};
var year = DateTime.Now.Year;
var cal = System.Threading.Thread.CurrentThread.CurrentCulture.Calendar;
//Generate the months and dates and left join with the values from the DB
var q = from month in Enumerable.Range(1, cal.GetMonthsInYear(year))
select new
{
Dates = from date in Enumerable.Range(1,
cal.GetDaysInMonth(year, month))
.Select(day => new DateTime(year, month, day))
join tmp in values on date equals tmp.Date into g
from value in g.DefaultIfEmpty()
select new
{
Date = date,
Value = value == null ? new Nullable<Decimal>() : value.Value
}
};
//bind the query to the outer repeater
repMonths.DataSource = q;
repMonths.DataBind();
从DB 填充DTO
public class DateValue
{
public DateTime Date { get; set; }
public decimal Value { get; set; }
}
ASPX-
<table border="1">
<asp:Repeater runat="server" ID="repMonths">
<ItemTemplate>
<tr>
<asp:Repeater runat="server" ID="repDays" DataSource='<%# DataBinder.Eval(Container.DataItem, "Dates") %>'>
<ItemTemplate>
<td>
<%# DataBinder.Eval(Container.DataItem, "Value") %>
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
我要检查的两件事是
- viewstate的大小。对于大量的服务器控件,这可能会很快失控
- 如何查询数据。糟糕的查询和无索引的模式可能会导致性能下降
我们可以假设该表是使用webforms表对象构建的吗?如果是这样,这就是你的问题。这给viewstate带来了巨大的、不必要的税收。而是建立表示UI数据结构的对象。从这个对象集合中,使用标准html对象(而不是webforms服务器控件)创建使用。
例如,您可以使用中继器并禁用特定控件的视图状态。使用页眉、页脚和正文模板,构建一个html表
<asp:repeater id="..." EnableViewState="false">
<headertempalte>
<table>
<thead>
<tr>
<th>...</th>
<th>...</th>
</tr>
</thead>
<body>
</headertemplate>
<footertemplate>
</body>
<tfoot>
...
</tfoot>
</table>
</footertemplate>
<itemtemplate>
<tr>
<td><%=Eval("...")%></td>
<td><%=Eval("...")%></td>
</tr>
</itemtemplate>
</asp:repeater>
这只是一个例子,我相信模板需要调整来修复你的确切布局,但这应该足以让你开始。