! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

ADO.NET 및 Entity Framework용 데이터 커넥터를 사용하여 CRUD REST API 빌드 > 블로그 & Tips

본문 바로가기

ComponentOne

블로그 & Tips

ADO.NET 및 Entity Framework용 데이터 커넥터를 사용하여 CRUD REST API 빌드

페이지 정보

작성자 MESCIUS 작성일 2024-04-18 09:28 조회 24회 댓글 0건

본문

첨부파일

빠른 시작 가이드
필요한 항목ComponentOne Data Services Edition Visual Studio 2022, .NET 8
참조 컨트롤C1.AdoNet.JSON(데이터 커넥터의 일부) C1.WPF.Grid(FlexGrid)
자습서 개념REST 서비스를 사용하여 .NET DataGrid(WPF)를 만들기, 읽기, 업데이트 및 삭제 기능이 포함된 JSON 데이터 소스에 완전히 연결하는 방법을 알아봅니다.


REST(Representational State Transfer)는 웹 서비스를 만들기 위해 사용되는 제약 조건의 집합을 정의하는 아키텍처 스타일입니다.


REST API는 처리 없이 간단하고 유연한 방법으로 웹 서비스에 액세스하는 방법입니다. RESTful API 서비스를 통해 CRUD(Create, Read, Update, Delete) 작업을 수행할 수도 있습니다. 


이 블로그에서는 Data Services Edition 제품의 일부인 ComponentOne JSON DataConnectors를 사용하여 RESTful API를 통해 CRUD 작업을 수행합니다.

ADO.NET 및 Entity Framework Core용 JSON DataConnectors는 ADO.NET 아키텍처 위에 작성되는 효과적인 데이터 연결을 위해 사용할 수 있으며, 설정된 데이터 액세스 기술을 기반으로 여러 종류의 데이터 소스에 액세스하는 공통 인터페이스를 활성화하는 고성능 데이터 공급자입니다.


데스크톱 .NET 응용 프로그램에서 CRUD 작업을 활성화하는 단계는 다음과 같습니다.


  1. XAML UI를 만들어 데이터 표시

  2. Web API 구성 만들기

  3. ADO.NET를 사용하여 FlexGrid를 JSON 데이터에 연결



XAML UI를 만들어 데이터 표시 


여기에서는 WPF용 FlexGridFlexGrid 컨트롤을 사용하여 CRUD 작업을 시각화합니다. WPF FlexGrid는 표 형식/개체 모델 데이터를 표시하기 위해 디자인된 DataGrid 컨트롤입니다.


UI에서 볼 수 있도록 XAML에서 FlexGrid를 추가합니다. FlexGrid의 ItemsSource를 설정하고 열을 각 속성과 바인딩합니다.

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
 
        <WrapPanel>
            <Button x:Name="_btnSyncChanges"
                    Background="White"
                    Cursor="Hand"
                    Width="200"
                    Content="Click here to Sync Changes with API"
                    Click="OnSyncChanges"></Button>
        </WrapPanel>
 
        <Grid x:Name="_syncView"
              Background="Black"
              Opacity="0.8"
              Grid.RowSpan="2"
              Visibility="Collapsed"
              Panel.ZIndex="1">
            <TextBlock HorizontalAlignment="Center"
                       FontSize="16"
                       Foreground="White"
                       VerticalAlignment="Center">Syncing...</TextBlock>
        </Grid>
 
        <c1:FlexGrid x:Name="_flexGrid" Margin="5, 0, 5, 5"
                     SelectionForeground="White"
                     SelectionBackground="Purple"
                     NewRowPosition="Bottom"
                     NewRowPlaceholder="Click here to add new product"
                     AutoGenerateColumns="False"
                     ItemsSource="{Binding Products}" Grid.Row="1">
            <!--Add Columns to the FlexGrid and bind these to the Product properties-->
            <c1:FlexGrid.Columns>
                <c1:GridColumn Binding="id" IsReadOnly="True" ColumnName="id" Width="*"></c1:GridColumn>
                <c1:GridColumn Binding="name" ColumnName="name" Width="*"></c1:GridColumn>
                <c1:GridColumn Binding="color" ColumnName="color" Width="*"></c1:GridColumn>
                <c1:GridNumericColumn Binding="price" Format="N2" ColumnName="price" Width="*"></c1:GridNumericColumn>
                <c1:GridColumn Binding="category" ColumnName="category" Width="*"></c1:GridColumn>
            </c1:FlexGrid.Columns>
        </c1:FlexGrid>
    </Grid>



Web API 구성 만들기  


C1JsonConnection 클래스를 사용하여 JSON 데이터 소스에 연결 설정. 연결을 설정하려면 연결 문자열을 인수로 제공해야 합니다. 로컬 파일에 연결하기 위해, DataModel 및 JsonPath 속성 외에 Uri 속성을 JSON 파일에 설정하여 연결 문자열을 만들 수 있습니다.


App.config 파일을 만들어 RESTful API를 위한 연결 문자열을 저장합니다.

아래 ConnectionStrings를 사용하여 프로젝트에 새로운 응용 프로그램 구성 파일을 추가합니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="GetProducts" connectionString="Data Model=Document; Uri='https://localhost:44321/products'; Json Path='$.products'"></add>
    <add name="AddUpdateProduct" connectionString="Data Model=Document; Uri='https://localhost:44321/products'; api config file='api_config.xml'; Json Path='$.products'"></add>
  </connectionStrings>
</configuration>


구성 파일을 사용하여 JSON 소스용 CRUD 작업을 지원하도록 ConnectionString의 APIConfigFile 속성을 설정할 수도 있습니다. 구성 파일이 있어야 합니다.


프로젝트에 AddUpdateProduct 연결 문자열의 API 구성을 위한 XML 파일을 만들어야 합니다.


HTTP JSON 소스용 구성을 만들려면 스키마를 구성해야 합니다. 각 스키마는 SelectOperation, InsertOperation, UpdateOperation, DeleteOperation의 네 섹션으로 구분해야 합니다.

<Api_Config>
    <Table name="products">
    <SelectOperation>
      <Uri>https://localhost:44321/products</Uri>
      <Method>Get</Method>
      <Response>
        <TableName name="products" type="string"/>
        <Column name="id" isKey="true" type="int">id</Column>
        <Column name="name" type="string">name</Column>
        <Column name="color" type="string">color</Column>
        <Column name="category" type="string">category</Column>
        <Column name="price" type="double">price</Column>
      </Response>
    </SelectOperation>
        <InsertOperation>
            <Uri>https://localhost:44321/products</Uri>
            <Method>Post</Method>
            <Body>
        <TableName name="products" type="string"/>
        <Column name="id" isKey="true" type="int">id</Column>
        <Column name="name" type="string">name</Column>
        <Column name="color" type="string">color</Column>
        <Column name="category" type="string">category</Column>
        <Column name="price" type="double">price</Column>
            </Body>
        </InsertOperation>
        <UpdateOperation>
            <Uri>https://localhost:44321/products</Uri>
            <Method>PUT</Method>
            <Body>
        <TableName name="products" type="string"/>
        <Column name="id" isKey="true" type="int">id</Column>
        <Column name="name" type="string">name</Column>
        <Column name="color" type="string">color</Column>
        <Column name="category" type="string">category</Column>
        <Column name="price" type="double">price</Column>
            </Body>
        </UpdateOperation>
        <DeleteOperation>
            <Uri>https://localhost:44321/products/{id}</Uri>
            <Method>DELETE</Method>
      <Paramter name="id" type="int">id</Paramter>
        </DeleteOperation>
    </Table>
</Api_Config>



ADO.NET를 사용하여  

FlexGrid를 JSON 데이터에 연결 


다음으로 ADO.NET를 사용하여 Flexgrid를 JSON 데이터 커넥터에 연결하고 CRUD 작업을 표시하는 방법을 알아보겠습니다.


먼저 보기의 데이터 소스 및 컨트롤러 역할을 할 ViewModel 클래스를 만듭니다.

그런 다음 FlexGrid의 ItemsSource에 바인딩되어야 하는 DataTable 속성을 추가하고, "GetProducts" 연결 문자열 도움을 받아 C1JsonDataAdapter를 사용하여 API에서 데이터를 가져오기 위한 메서드를 추가합니다.


이제 FlexGrid의 RESTful API에서 데이터를 읽을 수 있습니다.

public class ProductsViewModel : INotifyPropertyChanged
    {
        private DataTable _products;
 
        public DataTable Products
        {
            get
            {
                return _products;
            }
            set
            {
                _products = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Products)));
            }
        }
 
        public event PropertyChangedEventHandler? PropertyChanged;
 
        public async Task LoadProducts()
        {
            Products = await GetProductsTable();
            Products.DefaultView.Sort = "id";
            Products.Columns["id"].AutoIncrement = true;
            Products.Columns["id"].AutoIncrementSeed = Convert.ToInt64(Products.Compute("max([id])", string.Empty)) + 1;
            Products.Columns["id"].AutoIncrementStep = 1;
            Products.Columns["id"].Unique = true;
        }
        private async Task<DataTable> GetProductsTable()
        {
            var connString = ConfigurationManager.ConnectionStrings["GetProducts"].ConnectionString;
            using (var connection = new C1JsonConnection(connString))
            {
                await connection.OpenAsync();
                using (var adapter = new C1JsonDataAdapter(connection, "Select * from products"))
                {
                    var productsTable = new DataTable();
                    adapter.Fill(productsTable);
                    return productsTable;
                }
            }
        }
    }
}


다음으로 Create, UpdateDelete 작업을 구현합니다. 따라서 UI(Flexgrid)의 변경 사항에 따라 API가 수정됩니다.


ViewModel 클래스에서 Sync() 메서드를 만들어 Create, Update 및 Delete 작업을 구현합니다.

public async Task Sync()
        {
            var connString = ConfigurationManager.ConnectionStrings["AddUpdateProduct"].ConnectionString;
            using (var connection = new C1JsonConnection(connString))
            {
                await connection.OpenAsync();
                using (var adapter = new C1JsonDataAdapter())
                {
                    //Create
                    adapter.InsertCommand = new C1JsonCommand(connection);
                    adapter.InsertCommand.CommandText = "Insert into products (name, color, price, category) values (@Name, @Color, @Price, @Category);";
                    adapter.InsertCommand.Parameters.Add("@Name", "name");
                    adapter.InsertCommand.Parameters.Add("@Color", "color");
                    adapter.InsertCommand.Parameters.Add("@Price", "price");
                    adapter.InsertCommand.Parameters.Add("@Category", "category");
                    adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
 
                    //Update
                    adapter.UpdateCommand = new C1JsonCommand(connection);
                    adapter.UpdateCommand.CommandText = "Update products set name=@Name, color=@Color, price=@Price, category=@Category where id=@Id";
                    adapter.UpdateCommand.Parameters.Add("@Id", "id");
                    adapter.UpdateCommand.Parameters.Add("@Name", "name");
                    adapter.UpdateCommand.Parameters.Add("@Color", "color");
                    adapter.UpdateCommand.Parameters.Add("@Price", "price");
                    adapter.UpdateCommand.Parameters.Add("@Category", "category");
                    adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
 
                    //Delete
                    adapter.DeleteCommand = new C1JsonCommand(connection);
                    adapter.DeleteCommand.CommandText = "Delete from products where id=@Id";
                    adapter.DeleteCommand.Parameters.Add("@Id", "id");
                    adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
 
                    adapter.Update(Products);
                }
            }
        }


다음으로 UI에 버튼을 추가하여 모든 변경 사항을 동기화할 수 있습니다. 이렇게 하면 모든 변경 사항을 가져오고 이에 대해 사용자에게 알립니다.


그런 다음 ViewModel의 Sync() 메서드를 호출하여 모든 변경 사항을 RESTful API에 업데이트합니다.

private async void OnSyncChanges(object sender, RoutedEventArgs e)
{
    try
    {
        await _flexGrid.FinishRowEditing(false);
        var changes = _viewModel.Products.GetChanges();
 
        if (changes == null)
        {
            MessageBox.Show("No changes to sync", "No changes", MessageBoxButton.OK, MessageBoxImage.Information);
            return;
        }
        _syncView.Visibility = Visibility.Visible;
        await Task.Delay(500); //simulate delay
 
        string message = "Sync Complete.\n";
        //Check for Deleted Rows
        var deletedRows = changes.AsEnumerable().Where(x => x.RowState == DataRowState.Deleted).ToList();
        if (deletedRows.Count > 0)
            message += $"Deleted {deletedRows.Count} row(s).\n";
        //Check for Added Rows
        var addedRows = changes.AsEnumerable().Where(x => x.RowState == DataRowState.Added).ToList();
        if (addedRows.Count > 0)
            message += $"Added {addedRows.Count} row(s).\n";
        //Check for Modified Rows
        var modifiedRows = changes.AsEnumerable().Where(x => x.RowState == DataRowState.Modified).ToList();
        if (modifiedRows.Count > 0)
            message += $"Modified {modifiedRows.Count} row(s).";
         
        await _viewModel.Sync();
         
        _syncView.Visibility = Visibility.Collapsed;
        MessageBox.Show(message, "Sync Successfull", MessageBoxButton.OK, MessageBoxImage.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Sync Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}



다 끝났습니다! 


이제 WPF 응용 프로그램이 준비되었습니다.


Flexgrid에서 데이터를 편집, 추가 또는 제거할 수 있으며, 아래 GIF에 표시된 대로 데이터가 동기화된 후 RESTful 서비스에 반영됩니다.

CRUD REST API


전체 구현을 위해 샘플을 다운로드할 수 있습니다.



[추가방법] EntityFramework Core 사용하여 CRUD 구현


위에서는 표준 ADO.NET 접근 방식을 사용했습니다.

Entity Framework Core를 사용하여 동일한 기능이 어떻게 작동하는지 살펴보겠습니다. 이 섹션에서는 EntityFramework Core를 사용하여 CRUD 작업을 수행하는 방법을 설명합니다.


첫째, EntityFramework용 DbContext에서 파생된 ProductContext 클래스를 만듭니다.

이 클래스는 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있는 기본 데이터베이스를 사용하는 세션을 나타냅니다. 


그런 다음 FlexGrid의 ItemsSource에 바인딩되어야 하는 DbSet 속성을 추가합니다.

DbContext의 메서드를 재정의하여 "AddUpdateProduct" 연결 문자열의 도움을 받아 엔터티를 초기화하고 구성합니다.


이제 FlexGrid의 RESTful API에서 데이터를 읽고 DbContext에 변경 사항을 저장하여 RESTful API 데이터를 수정할 수 있습니다.

public partial class ProductContext : DbContext
    {
        public virtual DbSet<Product> Products { get; set; }
 
        public ProductContext()
        {
            Database.AutoTransactionsEnabled = false;
        }
 
        public ProductContext(DbContextOptions<ProductContext> options)
            : base(options)
        {
            Database.AutoTransactionsEnabled = false;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseJson(ConfigurationManager.ConnectionStrings["AddUpdateProduct"].ConnectionString);
            }
        }
 
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>(entity =>
            {
                 
                entity.ToTable("products");
                entity.HasChangeTrackingStrategy(ChangeTrackingStrategy.Snapshot);
                entity.HasKey(x => x.Id);
                entity.Property(e => e.Id).HasColumnName("id");
                entity.Property(e => e.Name).HasColumnName("name");
                entity.Property(e => e.Color).HasColumnName("color");
                entity.Property(e => e.Category).HasColumnName("category");
                entity.Property(e => e.Price).HasColumnName("price");
            });
        }
    }


다음으로 XAML 디자이너에 있는 버튼의 클릭 이벤트를 처리하여 모든 변경 사항을 동기화합니다.


모든 변경 사항을 가져오고 이에 대해 사용자에게 알립니다.

그런 다음 DbContext의 SaveChangesAsync() 메서드를 호출하여 모든 변경 사항을 RESTful API에 업데이트합니다.

private async void OnSyncChanges(object sender, RoutedEventArgs e)
{
    try
    {
        await _flexGrid.FinishRowEditing(false);
        var change = _context.ChangeTracker.DebugView;
 
        _syncView.Visibility = Visibility.Visible;
        await Task.Delay(500); //simulate delay
 
        string message = "Sync Complete.\n";
        //Check for Deleted Rows
        var deletedRows = change.ShortView.Split("\r\n").Where(x=>x.Contains("Deleted"));
        if (deletedRows.Count() > 0)
            message += $"Deleted {deletedRows.Count()} row(s).\n";
        //Check for Added Rows
        var addedRows = change.ShortView.Split("\r\n").Where(x => x.Contains("Added"));
        if (addedRows.Count() > 0)
            message += $"Added {addedRows.Count()} rows.\n";
        //Check for Modified Rows
        var modifiedRows = change.ShortView.Split("\r\n").Where(x => x.Contains("Modified"));
        if (modifiedRows.Count() > 0)
            message += $"Modified {modifiedRows.Count()} rows.\n";
        await _context.SaveChangesAsync();
        _syncView.Visibility = Visibility.Collapsed;
 
        if (deletedRows.Count() == 0 & addedRows.Count() == 0 & modifiedRows.Count() == 0)
        {
            MessageBox.Show("No changes to sync", "No changes", MessageBoxButton.OK, MessageBoxImage.Information);
            return;
        }
 
        MessageBox.Show(message, "Sync Successfull", MessageBoxButton.OK, MessageBoxImage.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Sync Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}


다 끝났습니다! 보시다시피 훨씬 더 적은 코드만 있어도 됩니다.  


전체 구현을 위해 샘플을 다운로드할 수 있습니다. WinForms용 FlexGrid를 사용하여 동일하게 구현할 수 있습니다.




지금 바로 ComponentOne을 다운로드하여 직접 테스트해보세요!

  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.