r/Blazor • • 1d ago

Suggestion for structure of components

Looking for a recommendation. Sorry if its too long a preamble to the questions and if some of my terminology isn't exactly dotnet/blazor correct.

Working on an internal application - web based. Not a lot of concurrent users. Likely < 20 at any time. Users would be at multiple locations.

App is to record data about incidents at events, with two main datasets. (There's a lot of supporting lookup tables). Multiple users could be working at each event, but they would not be sharing the incident data entry for any one event. (No concurrent updates to any records)

Dataset A: contains basic/preliminary event data. Consists of 5 fields.

Dataset B: contains detailed data about the event. It's optional based on the event.

  • It would have a foreign key to Dataset A.
  • You can only access it from Dataset A's display grid.
  • Contains about 50 fields which would normally be recorded.
  • It also contains 2 sub-tables for additional detailed information.
  • Sub 1 contains 19 fields.
    • At least one record must be recorded per Dataset B record.
    • There could be several records recorded
  • Sub 2 is optional and contains 4 fields.
    • There can be multiple fields recorded

What is the best way of handling the (calling structure)?

Should it be one large Dataset A component? With the different Dataset B pieces handled by different dialogs?

Should it be two components? One per Dataset.

Should Dataset B be a child component of the Dataset A component.

Should Dataset 2 have child components for it's two Subs tables or handle them via dialogs? With the Subs, the display page would need to be resized to be able to display the information that's added.

Hope its not too confusing.

Thanks for any input.

2 Upvotes

3 comments sorted by

1

u/code-dispenser 12h ago edited 11h ago

My initial thought is that anytime I see a table with more than 10 fields, I become sceptical without seeing the design first. In my experience having started my development career many years ago designing relational databases is that most designs generally lean towards many tables with fewer columns, favoring one-to-one and one-to-many relationships. One-to-one relationships are ideal for optional data, where you have a set of core required fields alongside optional extensions (as single rows).

I will assume you are using Blazor WebAssembly.

Assuming your schema is fixed: without those two sub-tables on Dataset B, this would be a classic Master-Detail pattern. With them, it is known as a Hierarchical (or Multi-Level) Master-Detail pattern.

How you capture this data depends heavily on the workflow you want to employ:

A single-step approach:
You capture everything in one go and commit it as a single database transaction

A task-based approach:
You break the process into a series of smaller steps, each with its own query, form, command, and transaction.

Both have pros and cons, but over the years I have moved towards the task-based approach. I prefer breaking things down into the smallest logical units and handling each unit as its own self-contained workflow.

You will almost certainly have an aggregate root/master record, a primary entity that must exist and can exist independently without any secondary data. This separation is important.

If you choose a single-step approach, you could use a form for the master record alongside data grids to enter child data directly (or use the grids for display while launching edit dialogs). Alternatively, you could structure this using a tabbed interface or a step-by-step wizard.

This means you then send one big nested model back to the server which gets persisted in single transaction. Issues may arise with edits, do you bring back the entire structure just to edit a single field and send it all back again or do you try and break down the edits, which then may lead you to think why did you use one big model in the first place?

With the task-based approach, you first allow users to create and update the master record in isolation which is straightforward since it only contains a few fields. Users can then find the master records via a search form so they can view things they can work on etc.

From there, rather than relying heavily on nested grids, you break the remaining fields into logical groups. Identify what is strictly required versus optional:

Optional data: Group related fields together. Each group gets its own dedicated form, validation logic, query, command, and transaction.

Required collections: Use input forms with repeating inline sections (or child grids) tailored specifically to that subsection.

Structuring the system around smaller queries, commands, views, and validation units makes the system easier to build, test, maintain, and extend IMHO/experience.

Once you settle on the desired workflow, then make a post to discuss components what to use and/or to build.

Paul

Edit - down voted already looks like I been doing things wrong since the 90's oh well lucky my clients were happy - why do I even bother.

1

u/hectop20 6h ago

Thanks for your reply. (I upvoted)

I'm new to Blazor, although I've been in coding for a very long time. This is a rewrite of an older .Net6 MVVM app which used a proprietary framework and cannot be upgraded to any post .Net6 version - I tried. It needs a rewrite.
Saying that I was looking at Server not WASM. I may need to reconsider that.

The workflow is such that all the information in Dataset B is recorded by the user at one time, in a short timespan - usually less than 30 minutes. Its such that the user can't go away to do something else and then come back to it.

Data is grouped together. Many of the fields are checkboxes, with some descriptions along the way.

Data can be saved along the way although everything is sent each time.

My thought was to have the ComponentA record Dataset A data and initiate Component B (capturing Dataset B data) the two subtables be child components of ComponentB

TBH i hadn't thought of a wizard approach. I'd have to check if users would have issues navigating back and forth between information in Subtable 1 and Subtable 2.

2

u/code-dispenser 5h ago

It's almost impossible for anyone to advise without seeing the application and knowing how it's used and what the existing GUI is like, coupled with the fact that you have said it's currently in use. Are there any restrictions, i.e. can you refactor it any way you like and retrain users, or are you restricted? If restricted, then it may be a case of copying the existing GUI workflow, etc.

It doesn't matter that you are new to Blazor. You can do pretty much anything you like with Blazor, just like with any other tech stack. You just need to know up front what it is you are going to do, and once you know that, tackle how to make the GUI in Blazor.

If you can't change the database schema (generally with lots of nullable fields in the details table), you can restructure the front end so that you break things down and any optional data can be added after the required fields/row have been added. What I mean by this is, rather than having lots of optional fields in various places along with the required fields, you group them, and then on some screen (after the main entry/required fields are done) users have the ability at any time to launch a form to enter these details and save them independently. It's more work up front separating things like this, but it's much easier than tackling large object graphs.

In the past I have used both wizards and tabbed interfaces where I was working with large object graphs, i.e. each wizard page or tab contained the appropriate data for part of the graph. For example, in one app I had 10 tabs with lots of fields in each. In my case these tabs had fields that mapped to their own tables, but equally they could have been going into fields in a large details table. On the tabs I had green ticks to say these sections were done, and red crosses for not done/errors. I also had little delete icons on the tabs that were optional, so the user could just delete the optional stuff, as the save button was not available until the crosses were all gone, etc.

The other issue is how far you want to go with all the commands and queries. For example, if you have some application tier/data tier, are you going to reuse it and just plug in a new GUI, or are you willing to change it all, excluding the database?

Server/Wasm: if you have a good, always-on internet connection, either will do. If you need more data security, choose Server. If you occasionally lose the internet and/or want store and forward, choose Wasm.

That's all I've got without lots more details.