An open API service indexing awesome lists of open source software.

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

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.