我们可以在ASP.NET中为pagemethod和webmethod使用相同的数据表吗?

Ath*_*hul 10 .net c# asp.net static webmethod

我正在尝试创建一个新的网页,我需要显示近10个不同的网格视图和图表.

Gridview在pageload事件中绑定,并且通过调用WebMethod使用jquery-ajax方法(使用amcharts以及highcharts)显示图表.

最初我执行页面的方式是在执行gridview(用于显示网格视图数据)和webmethods(用于绘制图表)的同一组存储过程之后.对于此页面,执行两次相同的sps(一个用于网格,另一个用于图表) ).为获取数据需要执行10个sps.

因此,为了提高页面性能,我创建了这样的静态数据表

static DataTable Report1;
Run Code Online (Sandbox Code Playgroud)

并且像这样捆绑了gridview.

private void gvbindReport1()
    {
        try
        {            
            Report1 = new DataTable();//refreshed datatable 
            DataSet ReportDS1 = objmvbl.GetReportGraph(ClientID, date_From, date_To);
            if (ReportDS1.Tables.Count > 0)
            {
                Report1 = ReportDS1.Tables[0];//bindinding data to static datatable

            }
            GdReport.DataSource = Report1;
            GdReport.DataBind();
        }
        catch (Exception ex)
        {
            Log.Errlog("Error Occured in  gvbindReport1 : " + ex.Message.ToString());
        }

    }
Run Code Online (Sandbox Code Playgroud)

在webmethod内部,我使用了相同的数据表来绘制图表

 [System.Web.Services.WebMethod]
    public static string GetDataReport1()
    {
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
        Dictionary<string, object> row;
        try
        {
            //processing for the data inside static datatable
            if (Report1.Rows.Count > 0)
            {
                foreach (DataRow dr in Report1.Rows)
                {
                    row = new Dictionary<string, object>();
                    foreach (DataColumn col in Report1.Columns)
                    {
                        row.Add(col.ColumnName, dr[col]);
                    }
                    rows.Add(row);
                }
            }
        }
        catch (Exception ex)
        {
            Log.Errlog("Error Occured in  GetDataReport WebMethod of Report Page : " + ex.Message.ToString());
        }

        return serializer.Serialize(rows);

    }
Run Code Online (Sandbox Code Playgroud)

有了这个我能够显示网格和图表.

现在请告诉我,这是处理web方法的正确方法吗?我已经读过webmethod与页面没有任何关系.请告诉我这种方法的缺点.

如果这是错误的,请建议更好的方法来改善页面性能?

suj*_*lil 6

不,这不是正确的方法.因为你已经声明了DataTableas static(一个静态变量具有应用程序范围而无法实例化)

用户将获得相同的结果(上次更新的值).

您可以在并发测试中实现这一点.

请检查以下方案:

考虑dtbl是在dataTable主页上初始化的静态,并在索引页面上创建另一个`datatable实例实例(两者都在页面加载中,如下所示).

public static DataTable dtbl;
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        dtbl = new DataTable();
        dtbl.Columns.Add("id");
        dtbl.Columns.Add("name");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dtbl.NewRow();
            dr["id"] = i.ToString();
            dr["name"] = i + 1;
            dtbl.Rows.Add(dr);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

索引页面

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        home.dtbl = new DataTable();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在每个页面加载中放置一个断点并运行应用程序,

  • 打开两个页面separate tab.
  • 刷新主页并检查列是否显示
  • 现在转到下一个选项卡(索引)并刷新它(为dt创建一个新实例).现在您将在家中获得新数据表,这将影响数据表.
  • 因此,如果同时执行这两个进程/页面,则两个页面都将获得最新值.这就是为什么我说它会在并发测试中实现这一点.

在这种情况下,您可以使用会话.请考虑以下代码:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        dtbl = new DataTable();
        dtbl.Columns.Add("id");
        dtbl.Columns.Add("name");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dtbl.NewRow();
            dr["id"] = i.ToString();
            dr["name"] = i + 1;
            dtbl.Rows.Add(dr);
        }
        if (((DataTable)Session["MyDatatable"]).Columns.Count < 0)
        {
            Session["MyDatatable"] = dtbl;
        }
        else
        {
            dtbl = (DataTable)Session["MyDatatable"];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Nab*_*apa 5

首先,不要在Web应用程序中使用静态变量作为一般经验法则.它们充当全局变量,不会针对每个请求进行实例化.

我也不建议你一直使用DataTables到你的UI层.相反,使用强类型对象.

  1. 创建您尝试绑定的对象的模型.

例如,如果您有一个名为person的表,其中包含以下字段.

Id | first_name | last_name | audit_ts
Run Code Online (Sandbox Code Playgroud)

您可以这样创建一个对象:

public class Person
{
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
  1. 现在在一个单独的函数中,在某些类中,您可以从数据库中调用存储过程,然后将person表中的表行转换为Person对象列表.

  2. 现在,您可以做的不是在两次调用存储过程来获取相同的数据(仅降低应用程序的性能),而是在Page_Load事件中代替绑定代码中的网格视图.在您调用webmethod之后简单地绑定HTML表格,我认为这是在您的代码隐藏中.您可以参考这篇文章,了解如何将您的HTML表与Ajax调用返回的JSON对象绑定.

  3. 这样,您只需对服务器和数据库进行一次调用,即可使用相同的数据来绑定表格和图表.