如何改进自定义的渲染';数据日历';在asp.net中

本文关键字:日历 asp net 数据 何改进 自定义 | 更新日期: 2023-09-27 18:19:58

我被要求改进ASP.Net C#页面。它目前显示了一种产品一年的每日价格。该页面看起来类似于墙规划师,每个输入控件都显示当天的价格。

该页面将用于更改该产品当年的价格。目前,"墙规划器"表控件正在代码后面的单元格中逐单元格生成。

有很多代码用于实现这一点,但本质上它做到了以下几点。

建立了一个表。。。动态

  1. 已定义新表控件
  2. 定义了12个新的TableRow控件(月)
  3. 每行添加了31个TableCell控件(每个控件都有一个唯一的id,例如cell_yy_mm_dd)

它充满了数据

  1. 从数据库中检索365天的价格(价格和日期)
  2. Foreach用于在数据集上循环
  3. 使用TableCells id检查的日期。如果匹配,则向单元格中添加一个新的TextBox

这给服务器带来了巨大的压力(特别是内存使用)。它似乎设计过度了,一定有更好的方法!

实现这种功能的更好方法是什么?

如何改进自定义的渲染';数据日历';在asp.net中

这就是我解决问题的方法。使用两个中继器,一个用于月,一个为天。使用当前日历,我可以使用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>

我要检查的两件事是

  1. viewstate的大小。对于大量的服务器控件,这可能会很快失控
  2. 如何查询数据。糟糕的查询和无索引的模式可能会导致性能下降

我们可以假设该表是使用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>

这只是一个例子,我相信模板需要调整来修复你的确切布局,但这应该足以让你开始。