Seamlessly Perform Batch CRUD Operations in Blazor Scheduler with ODATA Adaptor
Tags: blazor, scheduler, webdev, odata
Published: 2023-08-28 14:59:13

---
title: Seamlessly Perform Batch CRUD Operations in Blazor Scheduler with ODATA Adaptor
published: true
date: 2023-08-23 11:51:22 UTC
tags: blazor, scheduler, webdev, odata
canonical_url: https://www.syncfusion.com/blogs/post/batch-crud-blazor-scheduler-odata.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfrrndzztdrf01iyw059.png
---
This blog explains how to perform batch CRUD operations in the Syncfusion Blazor Scheduler with an ODATA adaptor using .NET 7.

The Syncfusion [Blazor Scheduler](https://www.syncfusion.com/blazor-components/blazor-scheduler "Blazor Scheduler") is a fully featured event calendar component that helps users manage their time efficiently. It facilitates easy resource scheduling and the rescheduling of events or appointments through editor pop-ups, drag and drop, and resizing actions.

According to [Wikipedia](https://en.wikipedia.org/wiki/Open_Data_Protocol "Wikipedia: Open Data Protocol"), “Open Data Protocol (OData) is an open protocol that allows the creation and consumption of queryable and interoperable [REST](https://en.wikipedia.org/wiki/REST "Wikipedia: Representational state transfer") [APIs](https://en.wikipedia.org/wiki/Application_programming_interface "Wikipedia: API") in a simple and standard way.” [OData batching](https://www.odata.org/getting-started/advanced-tutorial/#batch "OData batching") allows users to combine multiple requests into one POST request, then receive a full report back from an OData-enabled API with the status. So, you can easily create, edit, and delete recurring events using OData batching.

Let’s get started!

## Prerequisites

Make sure the following packages have global installations in your environment:

- [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/ "Visual Studio 2022")
- [.NET 7.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-7 "What's new in .NET 7")

## Creating a Blazor WebAssembly app

Let’s first create a new Blazor WebAssembly app using .NET 7.0:

1.Open Visual Studio 2022.
2.Navigate to **File -> New -> Project**.
3.Then, choose **Create a new project**. Select the **Blazor WebAssembly** app and click **Next**.
4.Provide a name for your project and click **Next**. In this example, we’ve provided the name **BlazorSchedulerCrud**.
5.Select **.NET 7.0** as the **Framework** type and choose the **Configure for HTTPS** and **ASP.NET Core Hosted** radio buttons.
6.Finally, click **Create**. Refer to the following image. ![.NET 7.0 framework selection](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/NET-7.0-frame-work-selection.png) Refer to the following output image.
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Creating-a-Blazor-WebAssembly-app.png" alt="Creating a Blazor WebAssembly app" style="width:100%">

  <figcaption>Creating a Blazor WebAssembly app</figcaption>

</figure>

7.Now, add the Blazor Scheduler component to your app using this [documentation](https://blazor.syncfusion.com/documentation/scheduler/getting-started#adding-component-package-to-the-application "Getting started with Blazor Scheduler").
8.We will use the **Entity Framework Core** and **OData** to manipulate data sets through CRUD operations. So, install the [Microsoft.AspNetCore.OData](https://www.nuget.org/packages/Microsoft.AspNetCore.OData "Microsoft.AspNetCore.OData Nuget package") and [Microsoft.EntityFrameworkCore.InMemory](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.InMemory/8.0.0-preview.2.23128.3 "Microsoft.EntityFrameworkCore.InMemory NuGet package") NuGet packages.

## Creating models

Let’s create an [event model](https://blazor.syncfusion.com/documentation/scheduler/appointments#event-fields "Event fields in Blazor Scheduler") class named Appointment in the **Appointment.cs** file in the Shared project. ![Appointment model](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Appointment-model.png)

Refer to the following code example.

```csharp
public class Appointment
{
    public int Id { get; set; }
    public string? Subject { get; set; }
    public string? Location { get; set; }
    public DateTime? StartTime { get; set; }
    public DateTime? EndTime { get; set; }
    public string? StartTimezone { get; set; }
    public string? EndTimezone { get; set; }
    public bool? IsAllDay { get; set; }
    public bool? IsBlock { get; set; }
    public bool? IsReadOnly { get; set; }
    public int? FollowingID { get; set; }
    public string? RecurrenceRule { get; set; }
    public int? RecurrenceID { get; set; }
    public string? RecurrenceException { get; set; }
    public string? Description { get; set; }
}
```

## Creating a database and context

Next, we will create a database based on the models in this app using the [Entity Framework Core InMemory Database Provider](https://learn.microsoft.com/en-us/ef/core/providers/in-memory/?tabs=dotnet-core-cli "EF Core In-Memory Database Provider"). After creating the database, we should add the data to it to retrieve the initial appointments. In this app, the local database is named Events.

The next step is to create a context for the database. Create a **ScheduleDataContext** class under the **Models** folder in the server project. Refer to the following image. ![Creating database and context](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Database-context.png)

In the **ScheduleDataContext** class, configure the database model ( **Appointment** ). Refer to the following code example.

```csharp
public partial class ScheduleDataContext : DbContext
{

    public ScheduleDataContext(DbContextOptions<ScheduleDataContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Appointment> EventsData { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
            
    }

}
```

Thus, we have successfully created the database and its context.

## Configuring the database and batch OData

1.Register the **ScheduleDataContext** class and **OData** in the **ConfigureServices** section of the **Program.cs** file. Refer to the following code example.
```csharp
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddDbContext<ScheduleDataContext>(options => options.UseInMemoryDatabase("Events"));
builder.Services.AddOData();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
```

2.We can enable [batching](https://devblogs.microsoft.com/odata/all-in-one-with-odata-batch/ "Article: All in One with OData $Batch") in ASP.NET Core 7.0 apps by making these two changes. Assume the Blazor app is leveraging the EDM (Entity Data Model) approach for communicating OData queries. First, in the **Program.cs** file, add the following code.
```csharp
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();

app.UseRouting();

IEdmModel GetEdmModel()
{
    var odataBuilder = new ODataConventionModelBuilder();
    odataBuilder.EntitySet<Appointment>("Appointment");
    return odataBuilder.GetEdmModel();
}

app.MapRazorPages();
app.MapControllers();
app.Select().Filter().Expand().OrderBy();
app.MapODataRoute(
    routeName: "odata",
    routePrefix: "odata",
    model: GetEdmModel(),
    batchHandler: new DefaultODataBatchHandler());
app.MapFallbackToFile("index.html");
```

3.Add the OData Batching middleware and default OData batch handler like in the following code example.
```csharp
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseODataBatching();
app.UseHttpsRedirection();

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();

app.UseRouting();

IEdmModel GetEdmModel()
{
    var odataBuilder = new ODataConventionModelBuilder();
    odataBuilder.EntitySet<Appointment>("Appointment");
    return odataBuilder.GetEdmModel();
}

app.MapRazorPages();
app.MapControllers();
app.Select().Filter().Expand().OrderBy();
app.MapODataRoute(
    routeName: "odata",
    routePrefix: "odata",
    model: GetEdmModel(),
    batchHandler: new DefaultODataBatchHandler());
app.MapFallbackToFile("index.html");
```

**Note:** Add the OData Batching (**app.UseODataBatching();**) before using the routing.

## Adding controllers

Now, we need to create controllers to perform CRUD actions with the ODataV4 service. Create the **AppointmentController** under the **Controllers** folder in the server project to easily retrieve, update, and remove event data in the database.

```csharp
namespace BlazorSchedulerCrud.Server.Controllers
{
    public class AppointmentController : ODataController
    {
        private ScheduleDataContext _db;
        public AppointmentController(ScheduleDataContext context)
        {
            _db = context;
            if (context.EventsData.Count() == 0)
            {
                foreach (var b in DataSource.GetEvents())
                {
                    context.EventsData.Add(b);
                }
                context.SaveChanges();
            }

        }
        [HttpGet]
        [EnableQuery]
        public IActionResult Get()
        {
            return Ok(_db.EventsData);
        }

        public async Task Post([FromBody] Appointment events)
        {
            _db.EventsData.Add(events);
            await _db.SaveChangesAsync();
        }

        public async Task Put([FromODataUri] int key, [FromBody] Appointment events)
        {
            var entity = await _db.EventsData.FindAsync(key);
            _db.Entry(entity).CurrentValues.SetValues(events);
            await _db.SaveChangesAsync();
        }

        public async Task Patch([FromODataUri] int key, [FromBody] Appointment events)
        {
            var entity = await _db.EventsData.FindAsync(key);
            _db.Entry(entity).CurrentValues.SetValues(events);
            await _db.SaveChangesAsync();
        }

        public async Task Delete([FromODataUri] int key)
        {
            var od = _db.EventsData.Find(key);
            _db.EventsData.Remove(od);
            await _db.SaveChangesAsync();
        }
    }
}
```

## Configure OData service in Blazor Scheduler

Finally, let’s render the Syncfusion Blazor Scheduler component in the **Index.razor** file in the client project with the OData service. Use the [data manager](https://blazor.syncfusion.com/documentation/data/getting-started "Getting started with Blazor DataManager component") to perform data processing between the Blazor Scheduler and OData service. Refer to the following code example.

```csharp
@using Syncfusion.Blazor.Schedule
@using Syncfusion.Blazor.Data
@using BlazorSchedulerCrud.Shared

<SfSchedule TValue="Appointment" Height="530px" @bind-SelectedDate="@SelectedDate">
    <ScheduleEventSettings Tvalue="Appointment">
        <SfDataManager Url="https://localhost:7146/odata/Appointment" Adaptor="Adaptors.OdataV4Adaptor"></SfDataManager>
    </ScheduleEventSettings>
</SfSchedule>

@code {
    public Query QueryData = new Query().From("Appointment");
    public DateTime SelectedDate = new DateTime(2023, 01, 09);
}
```

After synchronizing the OData service with the Blazor Scheduler, we can easily retrieve data from the OData service even at the initial load of the Blazor Scheduler.

## Performing batch CRUD operations in Blazor Scheduler with OData

We have completed all the required configurations. Let’s perform batch CRUD operations in Blazor Scheduler with OData!

### Create

We can create recurring events using a more detailed editor window. To do so, double-click on a cell to open the editor window. Enter the desired field values and press **Save**  to create recurring events. ![Create Recurrence Event](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Create-Recurrence-Event.gif)

### Update

To update an event, double-click on the required event. It will prompt you to confirm whether you need to edit the event or series. Select **Edit Series**. Now, the default editor window will open. In it, you can update the appointment details: subject, location, start and end time, time zone, description, and other recurrence options. Finally, select **Save** to update the event. ![Update Recurrence Event](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Update-Recurrence-Event.gif)

### Delete

Double-clicking an event prompts you to confirm whether you need to edit the event or series. Select **Edit Series.** Now, the default editor window will open with a **Delete**  button at the bottom-left to allow you to delete the recurrence appointments.

**Note:** When deleting an appointment through this editor window, the delete alert confirmation will not be shown, and the events will be deleted immediately.

You can also select the recurring appointments and press the **Delete** key, which prompts you to confirm whether you need to delete the event or series. You can choose **Delete Series** to delete the recurrence appointments. ![Delete Recurrence Event](https://www.syncfusion.com/blogs/wp-content/uploads/2023/08/Delete-Recurrence-Event-1.gif)

**Note:** For more details, refer to [our documentation](https://blazor.syncfusion.com/documentation/scheduler/crud-actions "Getting Started with CRUD actions in Blazor Scheduler Component").

## GitHub reference

You can check out the complete working example for [this blog’s contents on GitHub](https://github.com/SyncfusionExamples/Blazor-Scheduler-CRUD-using-ODATA-adaptor "Performing CRUD operations in Blazor Scheduler using ODATA adaptor GitHub demo").

## Summary

Thanks for reading! In this blog, we’ve seen how to perform batch CRUD operations in the Syncfusion [Blazor Scheduler](https://www.syncfusion.com/blazor-components/blazor-scheduler "Blazor Scheduler") with the OData adaptor in .NET 7. Try out these steps and leave your feedback in the comments section below!

The new version of Essential Studio is available for existing customers on the [License and Downloads](https://www.syncfusion.com/account/downloads "Essential Studio license and downloads page") page. If you are not a Syncfusion customer, try our 30-day [free trial](https://www.syncfusion.com/downloads "Get free evaluation of Essential Studio products") to check out our available features.

For questions, you can contact us through our [support forums](https://www.syncfusion.com/forums "Syncfusion Support Forums"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/ "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Create Blazor CRUD Application with PostgreSQL and Dapper](https://www.syncfusion.com/blogs/post/create-blazor-crud-application-with-postgresql-and-dapper.aspx "Blog: Create Blazor CRUD Application with PostgreSQL and Dapper")
- [How to Build a Blazor CRUD Application with Dapper](https://www.syncfusion.com/blogs/post/build-blazor-crud-application-with-dapper.aspx "Blog: How to Build a Blazor CRUD Application with Dapper")
- [How to Build a Blazor WebAssembly CRUD Application with Entity Framework](https://www.syncfusion.com/blogs/post/how-to-build-a-blazor-wasm-crud-application-with-entity-framework.aspx "Blog: How to Build a Blazor WebAssembly CRUD Application with Entity Framework")
- [How to Access Microsoft Graph Calendar Events with Syncfusion Blazor Scheduler](https://www.syncfusion.com/blogs/post/how-to-access-microsoft-graph-calendar-events-with-syncfusion-blazor-scheduler.aspx "Blog: How to Access Microsoft Graph Calendar Events with Syncfusion Blazor Scheduler")