如何使用Sqldependency自动更新页面加载

时间:2014-10-09 11:31:04

标签: c# asp.net forms sqldependency

我正在尝试从Web表单类创建并运行sqldependency方法,其中我有一个" UpdateMethod",我使用窗口形式作为参考实现。
但是,当数据库发生更改时,方法的Web表单版本不会在客户端自动更新页面加载,而窗口表单则会更新。

窗口表单方法版本:

   delegate void GridDelegate(DataTable table);      
   private void UpdateGrid()
    {
        string sql = "SELECT * FROM [dbo].[User]";
        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection(connectionstring))
        {
            using (SqlCommand cmd = new SqlCommand(sql, con))
            {
                con.Open();
                dep = new SqlDependency(cmd); //Passing Command to SQL dependency 
                dep.OnChange += dep_OnChange;
                using (SqlDataReader rdr = cmd.ExecuteReader())
                {
                    dt.Load(rdr);
                }
            }
        }
        dataGridView1.Invoke((GridDelegate)delegate(DataTable table)
        { dataGridView1.DataSource = table; }, dt);
    }

该方法的Web表单版本:

      private void UpdateGrid()
    {
        string sql = "SELECT * FROM [dbo].[User] order by uploadDate desc";
        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection(GetConnectionString()))
        {

            try 
            {
                using (SqlCommand cmd = new SqlCommand(sql, con))
                {
                    con.Open();
                    SqlDependency dep;
                    dep = new SqlDependency(cmd); //Passing Command to SQL dependency 
                    dep.OnChange += dep_OnChange;

                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        dt.Load(rdr);
                        // GridView1.DataSource = rdr;
                    }

                }

            }

            catch (Exception ex)
            {
                throw ex;
            }
        }
        GridView1.DataSource = dt;
        GridView1.DataBind();
    }

我尝试在网络表单版本中添加一个try..Catch语句,但我没有收到任何错误。请告知我如何进一步测试此方法,以解决此问题。任何提示/建议将是最受欢迎的。谢谢

1 个答案:

答案 0 :(得分:0)

这是一个模型。我没有可以使用的SQL服务器;因此我用计时器(线程)完成了我的例子。我已将SignalR用于此目的。确保浏览器也有点现代(IE10 +,Chrome,Mozilla等支持websockets)。

  1. 使用构造函数
  2. 创建集线器类

    构造函数初始化并触发计时器线程。线程执行代码,指示集线器调用客户端上的特定js方法(即连接到集线器的所有浏览器)。

    这个特殊的js方法将托管逻辑以刷新我们在更新面板内的gridview。

    1. 编写必要的javascript以进行刷新(aspx)
    2. aspx页面设计简单。它有一个updatepanel,你有一个绑定到sqldatasource的gridview,以及一个主要负责刷新网格数据的链接按钮(服务器端)。这个代码很简单,稍后会在下面显示。你可以注意到,为了使刷新工作,我们模拟了LinkBut​​ton控件的手动点击(在udpatepanel中托管)。

      1. 编写必要的逻辑以连接集线器(aspx)
      2. 这是连接到集线器的代码,并写入在收到服务器消息时应该调用的js方法。

        还要确保将owin启动类文件添加到项目中。有关更多信号器的信息,请参阅SignalR tutorials


        DataHub.cs

        using Microsoft.AspNet.SignalR;
        using System.Threading;
        using System.Diagnostics;
        
        namespace WebApp.SignalR.GridUpdatePanel
        {
            public class DataHub : Hub
            {
        
                public DataHub()
                {
                    Debug.Print("Ctor executed...");
                    Timer tmr = new Timer(new TimerCallback(this.RefreshThread), null, 1000, 5000);
                }
        
                //Method which invokes the client js code...
                public void Refresh()
                {
                    Clients.All.refreshData();            
                }
        
                public void RefreshThread(object obj)
                {
                    Debug.Print("RefreshThread Called...");
                    Refresh();
                }
            }
        }
        

        SignalRPage.aspx

        <%@ Page Title="SignalR Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="SingalRPage.aspx.cs" Inherits="WebApp.SignalR.GridUpdatePanel.SingalRPage" %>
        <asp:Content ID="Content1" ContentPlaceHolderID="cphPageHeadScripts" runat="server">
        </asp:Content>
        <asp:Content ID="Content2" ContentPlaceHolderID="cphPageBody" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <asp:Label ID="Label1" runat="server"></asp:Label>
                    <br />
                    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" DataSourceID="SqlDataSource1" EmptyDataText="There are no data records to display.">
                        <Columns>
                            <asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True" SortExpression="Id" />
                            <asp:BoundField DataField="PName" HeaderText="PName" SortExpression="PName" />
                            <asp:BoundField DataField="PAge" HeaderText="PAge" SortExpression="PAge" />
                        </Columns>
                    </asp:GridView>
                    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:PersonsDbConnectionString1 %>" DeleteCommand="DELETE FROM [Persons] WHERE [Id] = @Id" InsertCommand="INSERT INTO [Persons] ([Id], [PName], [PAge]) VALUES (@Id, @PName, @PAge)" ProviderName="<%$ ConnectionStrings:PersonsDbConnectionString1.ProviderName %>" SelectCommand="SELECT [Id], [PName], [PAge] FROM [Persons]" UpdateCommand="UPDATE [Persons] SET [PName] = @PName, [PAge] = @PAge WHERE [Id] = @Id">
                        <DeleteParameters>
                            <asp:Parameter Name="Id" Type="Int32" />
                        </DeleteParameters>
                        <InsertParameters>
                            <asp:Parameter Name="Id" Type="Int32" />
                            <asp:Parameter Name="PName" Type="String" />
                            <asp:Parameter Name="PAge" Type="Int32" />
                        </InsertParameters>
                        <UpdateParameters>
                            <asp:Parameter Name="PName" Type="String" />
                            <asp:Parameter Name="PAge" Type="Int32" />
                            <asp:Parameter Name="Id" Type="Int32" />
                        </UpdateParameters>
                    </asp:SqlDataSource>
                    <br />
                    <asp:LinkButton ID="LinkButton1" runat="server" CssClass="btn btn-default" OnClick="LinkButton1_Click">Refresh</asp:LinkButton>
                </ContentTemplate>
            </asp:UpdatePanel>
        </asp:Content>
        <asp:Content ID="Content3" ContentPlaceHolderID="cphPageBottomScripts" runat="server">
            <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
            <script src="signalr/hubs"></script>
        
            <script>
                function refreshGrid() {
                    console.log('grid refresh');
                    var lnk = document.getElementById('<%= LinkButton1.ClientID %>');
                    lnk.click();
                }
            </script>
            <script>
                $(function () {
                    var chat = $.connection.dataHub;
                    chat.client.refreshData = function () {
                        refreshGrid();
                    };
                    $.connection.hub.start().done(function () {
                        console.log('hub started...');
                    });
                });
            </script>
        </asp:Content>
        

        这里我使用了以下母版页。

        的Site.Master

        <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApp.SignalR.GridUpdatePanel.Site" %>
        
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Bootstrap 101 Template</title>
        
            <!-- Bootstrap -->
            <link href="/Content/bootstrap.min.css" rel="stylesheet">
        
            <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
            <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
            <!--[if lt IE 9]>
              <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
              <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
            <![endif]-->
            <asp:ContentPlaceHolder ID="cphPageHeadScripts" runat="server"></asp:ContentPlaceHolder>
        </head>
        <body>
            <form runat="server">
                <asp:ContentPlaceHolder ID="cphPageBody" runat="server"></asp:ContentPlaceHolder>
            </form>    
            <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
            <script src="/Scripts/jquery-1.9.1.min.js"></script>
            <!-- Include all compiled plugins (below), or include individual files as needed -->
            <script src="/Scripts/bootstrap.min.js"></script>
            <asp:ContentPlaceHolder ID="cphPageBottomScripts" runat="server"></asp:ContentPlaceHolder>
        </body>
        </html>
        

        最后,主aspx页面的代码隐藏如下:

        using System;
        using System.Diagnostics;
        
        namespace WebApp.SignalR.GridUpdatePanel
        {
            public partial class SingalRPage : System.Web.UI.Page
            {
                protected void Page_Load(object sender, EventArgs e)
                {
                    if (!IsPostBack)
                    {
                        Label1.Text = DateTime.Now.ToLongTimeString();
                    }
                }       
        
                protected void LinkButton1_Click(object sender, EventArgs e)
                {
                    Debug.Print("LinkButton1_Click");
                    Label1.Text = DateTime.Now.ToLongTimeString();
                    GridView1.DataBind();
                }
            }
        }