https://github.com/isnemoequaltrue/blazor-notification-db-record-change
Blazor notification on database recond changes
https://github.com/isnemoequaltrue/blazor-notification-db-record-change
Last synced: 11 months ago
JSON representation
Blazor notification on database recond changes
- Host: GitHub
- URL: https://github.com/isnemoequaltrue/blazor-notification-db-record-change
- Owner: IsNemoEqualTrue
- License: apache-2.0
- Created: 2019-11-03T19:36:34.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-01-15T06:57:28.000Z (over 6 years ago)
- Last Synced: 2025-04-05T19:34:06.607Z (about 1 year ago)
- Language: C#
- Size: 1.03 MB
- Stars: 39
- Watchers: 5
- Forks: 9
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Blazor client notifications on database record change
This example uses .NET CORE 3.0 Blazor server side to real-time update a HTML page on any database record changes.

Based on the observer design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

## Database table
Table for which I want to receive notifications every time its content changes:
```SQL
CREATE TABLE [dbo].[WeatherForecasts](
[City] [nvarchar](50) NOT NULL,
[Temperature] [int] NOT NULL
)
```
## Subject
Singleton instance wrapping SqlTableDependency and forwarding record table changes to subscribers:
```C#
public delegate void WeatherForecastDelegate(object sender, WeatherForecastChangeEventArgs args);
public class WeatherForecastChangeEventArgs : EventArgs
{
public WeatherForecast NewWeatherForecast { get; }
public WeatherForecast OldWeatherForecast { get; }
public WeatherForecastChangeEventArgs(WeatherForecast newWeatherForecast, WeatherForecast oldWeatherForecast)
{
this.NewWeatherForecast = newWeatherForecast;
this.OldWeatherForecast = oldWeatherForecast;
}
}
public interface IWeatherForecastService
{
public event WeatherForecastDelegate OnWeatherForecastChanged;
IList GetForecast();
}
public class WeatherForecastService : IWeatherForecastService, IDisposable
{
private const string TableName = "WeatherForecasts";
private SqlTableDependency _notifier;
private IConfiguration _configuration;
public event WeatherForecastDelegate OnWeatherForecastChanged;
public WeatherForecastService(IConfiguration configuration)
{
_configuration = configuration;
_notifier = new SqlTableDependency(_configuration["ConnectionString"], TableName);
_notifier.OnChanged += this.TableDependency_Changed;
_notifier.Start();
}
private void TableDependency_Changed(object sender, RecordChangedEventArgs e)
{
if (this.OnWeatherForecastChanged != null)
{
this.OnWeatherForecastChanged(this, new WeatherForecastChangeEventArgs(e.Entity, e.EntityOldValues));
}
}
public IList GetForecast()
{
var result = new List();
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 WeatherForecast
{
City = reader.GetString(reader.GetOrdinal("City")),
Temperature = reader.GetInt32(reader.GetOrdinal("Temperature"))
});
}
}
}
}
}
return result;
}
public void Dispose()
{
_notifier.Stop();
_notifier.Dispose();
}
}
```
Registration as Singleton:
```C#
public void ConfigureServices(IServiceCollection services)
{
...
...
services.AddSingleton();
}
```
## Observer
Index.razor page code (event subscriber):
```C#
@page "/"
@using DataBaseRecordChaneNotificationWithBlazor.Data
@inject IWeatherForecastService ForecastService
@implements IDisposable
Weather forecast
Immediate client notification on record table change with Blazor
City
Temp. (C)
@foreach (var forecast in forecasts)
{
@forecast.City
@forecast.Temperature
}
@code {
IList forecasts;
protected override void OnInitialized()
{
this.ForecastService.OnWeatherForecastChanged += this.WeatherForecastChanged;
this.forecasts = this.ForecastService.GetForecast();
}
private async void WeatherForecastChanged(object sender, WeatherForecastChangeEventArgs args)
{
var recordToupdate = this.forecasts.FirstOrDefault(x => x.City == args.NewWeatherForecast.City);
if (recordToupdate == null)
{
this.forecasts.Add(args.NewWeatherForecast);
}
else
{
recordToupdate.Temperature = args.NewWeatherForecast.Temperature;
}
await InvokeAsync(() =>
{
base.StateHasChanged();
});
}
public void Dispose()
{
this.ForecastService.OnWeatherForecastChanged += this.WeatherForecastChanged;
}
}
```
More info on https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency.