Skip to main content

Bind Components to Data with Entity Framework Core

  • 4 minutes to read

Entity Framework Core (EF Core) is a data access technology. EF Core uses a model to access data. The model consists of entity classes and a context object that stores information about a connection session with a database.

You can use EF Core in Blazor Server applications with DevExpress components: Grid, Pivot Grid, Scheduler, Combo Box and so on.

Note

Refer to Blazor Server and EF Core. Blazor WebAssembly prevents most direct connections and requests to databases. If you use a WASM Blazor application, you should have a separate application for database operations.

View Example: How to bind the Grid to data with Entity Framework Core

The steps below descirbe how to fetch data from a database to DevExpress components.

  1. Use Microsoft or DevExpress templates to create a Blazor Server project.

  2. Add EF NuGet packages to your project.

  3. Create a model for your database. In Visual Studio, select ToolsNuGet Package MangerPackage Manger Console and run the Scaffold-DbContext command.

    The following command generates entity classes for each table in the Northwind database and a context class for all the enitities and places them in the Model folder:

    Scaffold-DbContext "DataSource=<full-path-to-the-Northwind-database>" Microsoft.EntityFrameworkCore.Sqlite -OutputDir Models
    

    For more information about scaffolding, do any of the following:

    • Refer to the MSDN article.
    • Use the following command in the Package Manager console: get-help scaffold-dbcontext –detailed.
  4. Register a DbContext factory in the Program.cs file. Use the AddDbContextFactory extension method.

    using Microsoft.EntityFrameworkCore;
    // ...
    builder.Services.AddDbContextFactory<NorthwindContext>((sp, options) => {
        var env = sp.GetRequiredService<IWebHostEnvironment>();
        var dbPath = Path.Combine(env.ContentRootPath, "Northwind.db");
        options.UseSqlite("DataSource=" + dbPath);
    });
    
  5. In the .razor file, do the following:

    • In the @using section, specify Microsoft.EntityFrameworkCore and generated class namespaces.
    • In the @inject section, specify the DbContext factory.
    @using Microsoft.EntityFrameworkCore
    @using BindToData.Models
    @inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
    
  6. In the @code block, do the following:

    @implements IDisposable
    @* ... *@
    @code {
        IEnumerable<object> Data { get; set; }
        NorthwindContext Northwind { get; set; }
    
        protected override async Task OnInitializedAsync() {
            Northwind = NorthwindContextFactory.CreateDbContext();
            Data = await Northwind.Employees.ToListAsync();
        }
        @* ... *@
        public void Dispose() {
            Northwind?.Dispose();
        }
    }
    
  7. Add a DevExpress component to the page and bind it to the Data collection. The following code adds Grid to the page:

    <DxGrid Data="Data"
            KeyFieldName="EmployeeId">
        <Columns>
            <DxGridDataColumn FieldName="FirstName" />
            <DxGridDataColumn FieldName="LastName" />
            <DxGridDataColumn FieldName="Title" />
            <DxGridDataColumn FieldName="HireDate" />
        </Columns>
    </DxGrid>
    

    Grid

  8. Implement the Create, Update and Delete operations for the grid. To do this, add a command column to the grid and handle corresponding events. Refer to Edit Data for instructions.

    @page "/"
    @using Microsoft.EntityFrameworkCore
    @using BindToData.Models
    @inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
    @implements IDisposable
    
    <DxGrid Data="Data"
            CustomizeEditModel="OnCustomizeEditModel"
            EditModelSaving="OnEditModelSaving"
            DataItemDeleting="OnDataItemDeleting"
            KeyFieldName="EmployeeId">
        <Columns>
            <DxGridCommandColumn />
            <DxGridDataColumn FieldName="FirstName" />
            <DxGridDataColumn FieldName="LastName" />
            <DxGridDataColumn FieldName="Title" />
            <DxGridDataColumn FieldName="HireDate" />
        </Columns>
        <EditFormTemplate Context="editFormContext">
            <DxFormLayout>
                <DxFormLayoutItem Caption="First Name:">
                    @editFormContext.GetEditor("FirstName")
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Last Name:">
                    @editFormContext.GetEditor("LastName")
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Title:">
                    @editFormContext.GetEditor("Title")
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Hire Date:">
                    @editFormContext.GetEditor("HireDate")
                </DxFormLayoutItem>
            </DxFormLayout>
        </EditFormTemplate>
    </DxGrid>
    
    @code {
        IEnumerable<object> Data { get; set; }
        NorthwindContext Northwind { get; set; }
    
        protected override async Task OnInitializedAsync() {
            Northwind = NorthwindContextFactory.CreateDbContext();
            Data = await Northwind.Employees.ToListAsync();
        }
    
        void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e) {
            if(e.IsNew) {
                var editModel = (Employee)e.EditModel;
                editModel.EmployeeId = Data.Count() + 1;
            }
        }
    
        async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
            var editModel = (Employee)e.EditModel;
            // Re-query a data item from the database.
            var dataItem = e.IsNew ? editModel : Northwind.Employees.Find(editModel.EmployeeId);
            // Assign changes from the edit model to the data item.
            if (dataItem != null) {
                dataItem.FirstName = editModel.FirstName;
                dataItem.LastName = editModel.LastName;
                dataItem.Title = editModel.Title;
                dataItem.HireDate = editModel.HireDate;
                dataItem.EmployeeId = editModel.EmployeeId;
                // Post changes to the database.
                if (e.IsNew)
                    await Northwind.AddAsync(dataItem);
                await Northwind.SaveChangesAsync();
                // Reload the entire Grid.
                Data = await Northwind.Employees.ToListAsync();
            }
        }
    
        async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) {
            // Re-query a data item from the database.
            var dataItem = Northwind.Employees.Find((e.DataItem as Employee).EmployeeId);
            if (dataItem != null) {
                // Remove the data item from the database.
                Northwind.Remove(dataItem);
                await Northwind.SaveChangesAsync();
                // Reload the entire Grid.
                Data = await Northwind.Employees.ToListAsync();
            }
        }
    
        public void Dispose() {
            Northwind?.Dispose();
        }
    }