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.
The steps below describe how to fetch data from a database to DevExpress components.
Use Microsoft or DevExpress templates to create a Blazor Server project.
Add EF NuGet packages to your project.
Create a model for your database. In Visual Studio, select Tools → NuGet Package Manger → Package 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
.
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); });
In the
.razor
file, do the following:- In the
@using
section, specifyMicrosoft.EntityFrameworkCore
and generated class namespaces. - In the
@inject
section, specify the DbContext factory.
@using Microsoft.EntityFrameworkCore @using BindToData.Models @inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
- In the
In the
@code
block, do the following:- Declare an IEnumerable collection -
Data
. - Use the DbContext factory to create a new DBContext.
- Call the OnInitialized lifecycle method to load data from the DbContext.
- Implement the IDisposable interface and use the DbContext.Dispose method to track the context for the component lifetime.
@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(); } }
- Declare an IEnumerable collection -
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>
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; if (e.IsNew) await Northwind.AddAsync(editModel); else e.CopyChangesToDataItem(); // Post changes to the database. await Northwind.SaveChangesAsync(); // Reload the entire Grid. GridDataSource = await Northwind.Employees.ToListAsync(); } async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) { // Remove the data item from the database. Northwind.Remove(e.DataItem); await Northwind.SaveChangesAsync(); // Reload the entire Grid. GridDataSource = await Northwind.Employees.ToListAsync(); } public void Dispose() { Northwind?.Dispose(); } }