Code First Entity Framework core with full CRUD activity was used as the backend database in a C# Azure Function, with a Blazor WASM Web App. This replaced the use of LocalStorage as per a previous post which in turn replaced static app data.


The app is for helpers to volunteer for assistance tasks at a track meet. Entity Framework Core is used with the main entities being Round, Helper and Activity. A Helper volunteers and performs an Activity at a Meet (called a Round).


Previously, an Azure Static Web App was developed by extending the tutorial on that topic to contain 3 editable entities using the LocalStorage Nuget package to store the generated and modified entity data. CRUD actions on the each of the entities were implemented in Http Trigger C# Azure Functions using the LocalStorage API. The object of this exercise has now been completed by implementing the database backend using Entity Framework Core with an Azure SQL Database. The Code First approach is used to generate the database and the Entity Tables in that with the entity classes specified and the data context, add-migration and update-database commands in the Package Management Console action the database generation and modifications.

This version of the solution is available on GitHub: djaus2/mslearn-staticwebsite-3entities

In migrating from LocalStorage to EF, the article Using Entity Framework with Azure Functions was followed. Having worked through the tutorial the steps were applied to the Http GET Trigger Functions in the API project. This required:

  • Implementing the DBContext in the Startup (including getting the database connection string)
  • Passing that to the constructor in in Trigger Function class, replacing the entity data instance previously passed to it. Then
    • The using the entity database context to get the entity as a list. For example
    • See class HelpersGet on GitHub
    • Note that the ActivitysGet is a little more complicated than
      var helpers = await _context.Helpers.ToArrayAsync();
      

      as it has the other two entities as properties which also need to be in context:

      var activitys = await _context.Activitys.Include(activity=>activity.Helper).Include(activity => activity.Round).ToArrayAsync();
      
  • There was also some tidying up to remove the LocalStorage references.

The article did not cover POST, DELETE and PUT. These have now all been fully implemented in the API project.

DELETE and PUT Operations

In two Blazor GitHub projects previously discussed on this Blog Site, Code first Entity Framework Core used in Controllers. The previous versions of this application implemented a C# Azure Function for each CRUD operation, for each entity; each in its own class - as per the GET operations above. The migration then for these 3 CRUD operations were therefore implemented in a manner similar to to GET. In the function’s class, pass the database context to the class in its construction and replace the LocalStorag code with the EF code from those other projects. In the main, the latter part is :

    _context.<Add|Remove|Update>(helper);
    var result = await _context.SaveChangesAsync();

Note that there was no change to the Blazor code as they still are the same Http calls, and the Http Trigger function parameters haven’t changed.

Remove(PUT) is slightly more complex in that the entity Id is passed so it needs to be queried for using Linq.

Delete(DELETE) and Update(PUT) worked for all three entities without any drama. The classes can be viewed on GitHub in the API project here

POST Operation

Add(Post) worked OK for Helper and Round as they are ‘simple’ entities; no entities as properties. Posting a new Activity with references to existing Helper and Round gae the following error:

Executed 'ActivitysPost' (Failed, Id=a2e8a556-7b1b-4d0d-995c-65b9c494c802, Duration=26938ms)
[2021-05-03T05:04:29.141Z] System.Private.CoreLib: Exception while executing function: ActivitysPost. 
Microsoft.EntityFrameworkCore.Relational: An error occurred while updating the entries. 
See the inner exception for details. 
Core .Net SqlClient Data Provider: 
Cannot insert explicit value for identity column in table 'Helpers' 
... when IDENTITY_INSERT is set to OFF.

Error occurs on 2nd line of:

    _context.Add(activity);
    await _context.SaveChangesAsync();

NB: The following does work using a JSon string and Curl (ie Submitting new Helper and Round):

curl --header "Content-Type: application/json" --request POST --data "{'Name':'Recording','Quantity':1,'Round':{'No':1,'Description':'AVSL'},'Helper':{'Name':'FreedyFeelgood','Description':'BlaBlah'}}" http://localhost:7071/api/activitys/

Result returned:

{"id":6,"name":"Recording","quantity":1,"helper":{"id":13,"name":"FreedyFeelgood","description":"BlaBlah"},"round":{"id":7,"no":1,"description":"AVSL"}}

I did suspect that the problem was that Helper and Round used in the Add(POST) needed to be in context. I tried just getting the Helpers and Rounds from the DBContext but that didn’t work.

I posted a query on StackOverFlow EF Core Entity Post Error with entity that has other entities as properties Thankfully a solution was posted as an answer (thx,Ihusaan) with I accepted:

You can solve this by attaching the Round and the Helper for the activity by placing the following before the context.Add()!

    _context.Attach(activity.Helper);
    _context.Attach(activity.Round);

Azure Deployment

The app is deployed through GitHub Actions to Azure as a Static Web App in that whenever the solution is submitted to GitHub it builds and deploys it to Azure as an Azure Static Web App. That deployment worked OK for the previous non EF versions. The EF requires the SQL Connection string, which when running from the desktop in development phase, which uses local.settings.json for that. When deployed it needs to get that elsewhere as that file isn’t deployed … you don’t want that in GitHub on public view anyway.

This was managed by adding the option in Startup() to try getting the ConnectionString from the environment settings before trying local.settings.json. In the Azure Portal, in the App-Configuration Tab, you add a new Application Setting .. Add a new Name value pair.

There is also an option to create a Custom Domain. See the next blog post fo this.


All works now OK! 😄

We have a three entity Entity Framework Core API using C# Azure Functions where one entity has the other two in its properties. The database is Azure SQL. The client is a Blazor WASM WWeb App.

Deployed site is here
Please remove any data you place there, thx.


Additional

Now can reset the database by clearing it (See code here), and then send 3 new sets of entities as Json strings, to add to the database. (See code here)


Posts in this series: An Azure Static Web App with EF

  1. Multiple Entities and LocalStorage
  2. Index of the Repository
  3. Entity Framework Core Implementation This post.
  4. Cascade and SetNull Deletions

 TopicSubtopic
   
 This Category Links 
Category:Web Sites Index:Web Sites
  Next: > An Azure Static Web App with EF
<  Prev:   An Azure Static Web App with EF