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 descirbe 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 "Server=.; Database=Northwind; Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -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
Startup.cs
file (for .NET 5.0) or in theProgram.cs
file (for .NET 6.0). Use the AddDbContextFactory extension method.using Microsoft.EntityFrameworkCore; // ... public class Startup { // ... public void ConfigureServices(IServiceCollection services) { // ... services.AddDbContextFactory<NorthwindContext>((sp, options) => { var env = sp.GetRequiredService<IWebHostEnvironment>(); var dbPath = Path.Combine(env.ContentRootPath, "Northwind.mdf"); options.UseSqlServer("<your connection string>"); }); } // ... }
In the Razor page, 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 Project.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"> <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.
@using Microsoft.EntityFrameworkCore @inject IDbContextFactory<NorthwindContext> NorthwindContextFactory @implements IDisposable <DxGrid Data="Data" EditModelSaving="OnEditModelSaving" DataItemDeleting="OnDataItemDeleting" KeyFieldName="EmployeeId"> <Columns> <DxGridCommandColumn /> <DxGridDataColumn FieldName="FirstName" /> <DxGridDataColumn FieldName="LastName" /> <DxGridDataColumn FieldName="Title" /> <DxGridDataColumn FieldName="HireDate" /> </Columns> <EditFormTemplate Context="editFormContext"> @{ var employee = (Employee)editFormContext.EditModel; } <DxFormLayout> <DxFormLayoutItem Caption="First Name:"> <DxTextBox @bind-Text="@employee.FirstName" /> </DxFormLayoutItem> <DxFormLayoutItem Caption="Last Name:"> <DxTextBox @bind-Text="@employee.LastName" /> </DxFormLayoutItem> <DxFormLayoutItem Caption="Title:"> <DxTextBox @bind-Text="@employee.Title" /> </DxFormLayoutItem> <DxFormLayoutItem Caption="Hire Date:"> <DxDateEdit @bind-Date="@employee.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(); } async Task OnEditModelSaving(GridEditModelSavingEventArgs e) { var editModel = (Employee)e.EditModel; // Re-query a data item from the database. var dataItem = e.IsNew ? new Employee() : 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; // 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(); } }