실시간 업데이트로 Blazor FlexGrid에서 SQL Server로 데이터 바인딩
페이지 정보
작성자 GrapeCity 작성일 2020-11-09 16:07 조회 5,293회 댓글 0건본문
관련링크
컨트롤 및 강력한 C1DataCollection 라이브러리를 사용하면 간편하게 데이터 바인딩을 수행하고 SQL Server의 실시간 업데이트를 웹 앱에 표시할 수 있습니다. 는 데이터 표시 및 편집을 지원하는 빠른 Blazor 데이터그리드 컨트롤이며, C1DataCollection은 UI와 데이터베이스 간의 컬렉션을 관리하는 데 도움이 됩니다.
이 게시물에서는 FlexGrid를 사용하여 SQL Server 표를 Blazor 응용 프로그램에 표시하는 방법을 알아보겠습니다. 레코드가 데이터베이스에서 수정되면 C1DataCollection을 통해 자동으로 업데이트됩니다.
이 샘플을 구현하기 위해 다음과 같은 단계를 표시하겠습니다.
SQLServer 데이터베이스 설정
Blazor 응용 프로그램 만들기
SQL Server DataCollection 만들기
FlexGrid를 SQL Server DataCollection에 바인딩
SQL Server 데이터베이스 설정
이 샘플에서는 SqlExpress 인스턴스에 호스팅된 “TableDependencyDB”라는 데이터베이스를 “Products”라는 표와 함께 사용합니다. 표는 다음 SQL 문을 사용하여 생성되었습니다.
CREATE TABLE [dbo].[Products](
[Code] [nvarchar](50) NULL,
[Name] [nvarchar](50) NULL,
[Price] [decimal](18, 0) NULL
) ON [PRIMARY]
데모용으로 몇 가지 레코드를 추가했습니다.
Blazor 응용 프로그램 만들기
다음 단계는 서버 측 Blazor 응용 프로그램을 만들고, 나중에 사용할 NuGet 패키지인 C1.Blazor.Grid, C1.DataCollection.AdoNet 및 SqlTableDependency를 추가하는 것입니다.
Index.razor 페이지에서 아래와 같이 2개 열이 포함된 FlexGrid를 정의합니다.
<FlexGrid ItemsSource="Items" AutoGenerateColumns="false" Style="@("width:100%;")"> <FlexGridColumns> <GridColumn Binding="Name" Width="GridLength.Star"></GridColumn> <GridColumn Binding="Price"></GridColumn> </FlexGridColumns> </FlexGrid>
그리드는 나중에 SQL Server에서 채울 Products 컬렉션에 바인딩됩니다. 여기서는 아래와 같이 Product 클래스도 정의했습니다.
public class Product { public string Code { get; set; } public string Name { get; set; } public decimal Price { get; set; } }
서버 Blazor 응용 프로그램을 만들고 FlexGrid를 바인딩하는 방법에 대한 자세한 내용은 이전 문서인 에서 확인할 수 있습니다.
SQL Server DataCollection 만들기
다음 단계는 데이터베이스에서 항목을 유지 및 관리하기 위한 C1DataCollection을 만드는 것입니다. C1DataCollection은 ICollectionView의 표준 .NET 구현을 기반으로 하기 때문에 친숙하고 사용이 간편합니다. 또한 데이터 시각화 및 비동기 서버 작동과 같은 추가 기능을 제공합니다.
C1DataCollection 라이브러리에는 특정 컬렉션 시나리오를 위해 설계된 추가 데이터 컴포넌트가 포함됩니다. 여기서는 SQL Server 데이터베이스에서 데이터를 가져오려 하므로, Blazor FlexGrid에서 탐색하는 동안 이미 데이터를 채운 C1AdoNetCursorDataCollection을 상속하게 됩니다.
이 샘플의 핵심 구현은 아래의 SQLServerDataCollection 클래스입니다.
public class SQLServerDataCollection<T> : C1AdoNetCursorDataCollection<T>, IDisposable where T : class, new() { public SQLServerDataCollection(DbConnection connection, string tableName, IEqualityComparer<T> comparer = null, IEnumerable<string> fields = null) : base(connection, tableName, fields) { SynchronizationContext = SynchronizationContext.Current; Comparer = comparer ?? EqualityComparer<T>.Default; Notifier = new SqlTableDependency<T>(connection.ConnectionString, tableName); Notifier.OnChanged += OnTableDependencyChanged; Notifier.Start(); } public void Dispose() { Notifier.OnChanged -= OnTableDependencyChanged; Notifier.Stop(); } public SynchronizationContext SynchronizationContext { get; } public IEqualityComparer<T> Comparer { get; } private SqlTableDependency<T> Notifier { get; } private void OnTableDependencyChanged(object sender, RecordChangedEventArgs<T> e) { SynchronizationContext.Post(new SendOrPostCallback(o => { switch (e.ChangeType) { case ChangeType.Delete: { var index = InternalList.FindIndex(o => Comparer.Equals(o, e.Entity)); if (index >= 0) { var oldItem = InternalList[index]; InternalList.RemoveAt(index); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItem, index)); } } break; case ChangeType.Insert: { InternalList.Add(e.Entity); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, e.Entity, InternalList.Count - 1)); } break; case ChangeType.Update: { var index = InternalList.FindIndex(o => Comparer.Equals(o, e.Entity)); if (index >= 0) { var oldItem = InternalList[index]; InternalList[index] = e.Entity; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, e.Entity, oldItem, index)); } } break; } }), e); } }
ADO.NET은 변경 시 데이터베이스에서 알림을 수신하는 표준 방식을 사용하지 않으므로 개발을 간소화하기 위해 NuGet 패키지인 “SqlTableDependency”를 사용합니다.
컬렉션은 SqlTableDependency의 “OnChanged” 이벤트에 연결되며, 이에 따라 내부 항목을 업데이트하고 컬렉션의 OnCollectionChanged 메서드를 호출하여 변경 내용을 알리게 됩니다.
컬렉션은 이전에 생성되었던 동일한 스레드에서 CollectionChanged 이벤트를 발생하기 위해 SynchronizationContext에 대한 참조를 유지합니다.
IDisposable 구현은 수신기를 중지하고 이벤트에서 분리하는 데 중요합니다. 그러지 않으면 컬렉션은 페이지를 더 이상 사용하지 않게 된 후에도 계속 이벤트를 수신하게 됩니다.
컬렉션은 SqlTableDependency에서 수신된 항목이 컬렉션에 저장된 항목과 동일한지 여부를 결정하는 데 사용할 IEqualityComparer 형식의 매개 변수를 가져옵니다. 일반적으로 구현에서는 항목의 기본 키를 비교합니다.
동일한 제품을 확인하기 위해 다음과 같은 ProductComparer 클래스를 작성했습니다.
public class ProductComparer : EqualityComparer<Product> { public override bool Equals([AllowNull] Product x, [AllowNull] Product y) { if (null == x && null == y) return true; if (null == x || null == y) return false; return x.Code == y.Code; } public override int GetHashCode([DisallowNull] Product obj) { return obj.Code.GetHashCode(); } }
C1DataCollection의 ADO.Net 소스 사용에 대한 자세한 내용은 게시물에서 확인하세요.
FlexGrid를 SQL Server DataCollection에 바인딩
마지막 단계는 항목 컬렉션을 SQLServerDataCollection으로 채우는 것입니다. 레이저 페이지 초기화에서는 연결 문자열로 SqlConnection을 만든 다음 이를 SQLServerDataCollection 인스턴스에 전달하여 항목을 가져옵니다.
protected override void OnInitialized() { var sqlConnection = new SqlConnection(Configuration["ConnectionString"]); Items = new SQLServerDataCollection<Product>(sqlConnection, "Products", new ProductComparer()); }
연결 문자열은 appsettings.json 파일에 저장되며 페이지에 제공된 IConfiguration 인터페이스를 통해 가져옵니다.
예를 들면 다음과 같은 모양입니다.
@inject Microsoft.Extensions.Configuration.IConfiguration Configuration { "ConnectionString": "Data Source=PC\\SQLEXPRESS;Initial Catalog=TableDependencyDB;User ID=XXXX;Password=XXXX;" }
응용 프로그램을 실행할 때 SQL Server 데이터베이스 항목을 FlexGrid에서 보게 됩니다.
데이터베이스의 항목을 편집 또는 변경하면 데이터 그리드는 자동으로 업데이트됩니다. 이는 SqlServerDataCollection 클래스에서 변경 업데이트 이벤트를 처리했기 때문입니다.
NuGet에서 FlexGrid 및 C1DataCollection 라이브러리에 액세스할 수 있지만, 하여 Blazor FlexGrid 및 C1DataCollection의 추가 샘플에 액세스하는 방법도 권장합니다.
댓글목록
등록된 댓글이 없습니다.