前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[转]使用Blazor和SqlTableDependency进行实时HTML页面内容更新

[转]使用Blazor和SqlTableDependency进行实时HTML页面内容更新

作者头像
周星星9527
发布2021-02-03 10:16:21
1.5K0
发布2021-02-03 10:16:21
举报

原文:https://blog.csdn.net/mzl87/article/details/104264781

介绍

在这个简单的示例中,我们将看到发生在SQL Server数据库表更改时如何更新HTML页面,而无需重新加载页面或从客户端到服务器进行异步调用,而是从客户端获取此HTML刷新内容。服务器使用Blazor服务器端(.NET CORE 3.0)。

背景

之前,我发表了一篇有关“使用SignalR和SQLTableDependency进行记录更改的SQL Server通知”的文章。

上一篇文章使用了SignalR,以获取实时更改页面内容的通知。尽管功能正常,在我看来,SignalR不是那么直接和容易使用。

在Blazor的帮助下,从服务器到HTML页面的通知得到了极大的简化,从而获得了极好的抽象水平:使用Blazor——实际上——我们的代码只是C#和Razor语法。

使用代码

假设您有一个报告库存清单的页面,并且其中任何一种价格发生变化时,都需要刷新HTML页面。

SignalR之前,通常有一个使用Ajax 的JavaScript代码来定期(例如,每5秒一次)向服务器执行一个GET请求,以便检索可能的新价格并将其显示在HTML页面中。

如今,借助Blazor及其嵌入式SignalR功能,我们可以扭转这一趋势,并让服务器有责任仅在显示一些新价格时才更新HTML页面。

在下面的例子中,Blazor会负责更新HTML页面,而SqlTableDependency组件会负责在由于insert,update或delete而更改表内容时从SQL Server数据库获取通知:

我们必须使用Visual Studio 2019中的适当模板创建.NET CORE 3.0 Blazor Web应用程序。

然后,我们安装SqlTableDependency NuGet软件包,该软件包将负责获取有关记录表更改的通知:

代码语言:javascript
复制
PM> Install-Package SqlTableDependency

现在,对于此示例,让我们考虑要监视以下SQL Server表的值:

代码语言:javascript
复制
CREATE TABLE [dbo].[Stocks](
    [Code] [nvarchar](50) NULL,
    [Name] [nvarchar](50) NULL,
    [Price] [decimal](18, 0) NULL
) ON [PRIMARY]

因此,我们定义了一个C#模型类,该类映射了我们感兴趣的属性:

代码语言:javascript
复制
namespace BlazorApp1.Models
{
    public class Stock
    {
        public decimal Price { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
    }
}

现在,我们创建一个SqlTableDependency单例实例,将记录表更改包装并转发到Blazor页面。我们开始创建其接口:

代码语言:javascript
复制
using BlazorApp1.Models;
using System;
using System.Collections.Generic;
 
namespace BlazorApp1.Service
{
    public delegate void StockChangeDelegate(object sender, StockChangeEventArgs args);
 
    public class StockChangeEventArgs : EventArgs
    {
        public Stock NewValue { get; }
        public Stock OldValue { get; }
 
        public StockChangeEventArgs(Stock newValue, Stock oldValue)
        {
            this.NewValue = newValue;
            this.OldValue = oldValue;
        }
    }
 
    public interface ITableChangeBroadcastService : IDisposable
    {
        event StockChangeDelegate OnStockChanged;
        IList<Stock> GetCurrentValues();
    }
}

然后它实现:

代码语言:javascript
复制
using BlazorApp1.Models;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using TableDependency.SqlClient;
using TableDependency.SqlClient.Base.EventArgs;
 
namespace BlazorApp1.Service
{
    public class TableChangeBroadcastService : ITableChangeBroadcastService
    {
        private const string TableName = "Stocks";
        private SqlTableDependency<Stock> _notifier;
        private IConfiguration _configuration;
 
        public event StockChangeDelegate OnStockChanged;
 
        public TableChangeBroadcastService(IConfiguration configuration)
        {
            _configuration = configuration;
 
            // SqlTableDependency will trigger an event 
            // for any record change on monitored table  
            _notifier = new SqlTableDependency<Stock>(
                 _configuration["ConnectionString"], 
                 TableName);
            _notifier.OnChanged += this.TableDependency_Changed;
            _notifier.Start();
        }
 
        // This method will notify the Blazor component about the stock price change stock
        private void TableDependency_Changed(object sender, RecordChangedEventArgs<Stock> e)
        {
            this. OnStockChanged(this, new StockChangeEventArgs(e.Entity, e.EntityOldValues));
        }
 
        // This method is used to populate the HTML view 
        // when it is rendered for the first time
        public IList<Stock> GetCurrentValues()
        {
            var result = new List<Stock>();
 
            using (var sqlConnection = new SqlConnection(_configuration["ConnectionString"]))
            {
                sqlConnection.Open();
 
                using (var command = sqlConnection.CreateCommand())
                {
                    command.CommandText = "SELECT * FROM " + TableName;
                    command.CommandType = CommandType.Text;
 
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                result.Add(new Stock
                                {
                                    Code = reader.GetString(reader.GetOrdinal("Code")),
                                    Name = reader.GetString(reader.GetOrdinal("Name")),
                                    Price = reader.GetDecimal(reader.GetOrdinal("Price"))
                                });
                            }
                        }
                    }
                }
            }
 
            return result;
        }
 
        public void Dispose()
        {
            _notifier.Stop();
            _notifier.Dispose();
        }
    }
}

现在我们已经设置了数据库记录更改通知,是时候实现Blazor组件了。第一步,我们检索OnInitialized()方法中的所有当前股价,然后我们订阅有关表记录更改的事件通知,以刷新HTML视图:

代码语言:javascript
复制
@page "/"
@using BlazorApp1.Models
@using BlazorApp1.Service
 
@inject ITableChangeBroadcastService StockService
@implements IDisposable
 
<h1>Stock prices</h1>
 
<p>Immediate client notification on record table change with Blazor</p>
 
<table class="table">
    <thead>
        <tr>
            <th>Code</th>
            <th>Name</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var stock in stocks)
        {
            <tr>
                <td>@stock.Code</td>
                <td>@stock.Name</td>
                <td>@stock.Price</td>
            </tr>
        }
    </tbody>
</table>
 
@code {
    IList<Stock> stocks;
 
    protected override void OnInitialized()
    {
        // Subscription to table record change events
        this.StockService.OnStockChanged += this.StockChanged;
        this.stocks = this.StockService.GetCurrentValues();
    }
 
    // The event handler, will update the HTML view according to new stock value
    private async void StockChanged(object sender, StockChangeEventArgs args)
    {
        var recordToupdate = this.stocks.FirstOrDefault(x => x.Code == args.NewValue.Code);
 
        if (recordToupdate == null)
        {
            this.stocks.Add(args.NewValue);
        }
        else
        {
            recordToupdate.Price = args.NewValue.Price;
        }
 
        await InvokeAsync(() =>
        {
            base.StateHasChanged();
        });
    }
 
    public void Dispose()
    {
        this.StockService.OnStockChanged -= this.StockChanged;
    }
}

表格记录更改事件处理程序仅检查库存是否在显示的列表中,然后插入或更新其Price值。请注意,HTML将从Blazor自动刷新。为了更新HTML视图内容,我们不需要向浏览器发送任何通知,也不需要从浏览器向服务器发出任何轮询请求。

总而言之,我们将依赖性解析定义为单例:

代码语言:javascript
复制
namespace BlazorApp1
{
    public class Startup
    {
        …
        …
        public void ConfigureServices(IServiceCollection services)
        {
            …
            services.AddSingleton<ITableChangeBroadcastService, TableChangeBroadcastService>();
            …
        }
}

而且…别忘了设置数据库连接字符串!

代码语言:javascript
复制
{
    "ConnectionString": "Data Source=***; initial catalog=***; User ID=sa;Password=***"
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 传输过程数值模拟学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 使用代码
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档