Handling Data with Composite Models in C# and .NET

Introduction

Data representation is a fundamental aspect of software development that holds immense importance in creating efficient and reliable applications. In the digital age, where vast amounts of data are generated and processed daily, the way we represent and organize that data significantly impacts the performance, scalability, and maintainability of our software systems.

Composite Models in C# and .NET

Effective data representation ensures that information is structured in a logical and coherent manner, enabling seamless data access, manipulation, and analysis. It lays the foundation for efficient algorithms, optimal storage utilization, and streamlined data processing, making it a critical factor in the success of any software project. In this article, we will explore the significance of data representation in software development and how it influences the overall quality and functionality of our applications.

Composite models in C#

This article aims to explore composite models and their role in simplifying data representation. With the increasing complexity of data structures and the need for efficient management and processing of diverse data sources, composite models provide a powerful solution. By combining multiple data structures into a cohesive whole, composite models simplify the representation of complex information, making it easier to understand, access, and manipulate. We will discuss the benefits of using composite models for data representation, examine real-world use cases, and provide practical insights on implementing and leveraging composite models in software development.

Through this exploration, we aim to demonstrate how composite models can streamline data representation and improve the efficiency and maintainability of software applications.

Benefits of Composite Models in C#

  • Improved organization and maintainability: Composite models allow you to organize related data structures into a single cohesive unit. By combining multiple models into a composite model, you can simplify the overall structure of your code and make it easier to understand and maintain. This approach promotes modular design and reduces code duplication, leading to cleaner and more manageable codebases.
  • Streamlined data access: Composite models provide a convenient way to access and retrieve data from multiple sources or layers. Instead of making separate queries or operations for each individual model, you can work with the composite model to fetch all the required data in a single operation. This reduces the number of database round-trips or network requests, resulting in improved performance and efficiency.
  • Simplified data manipulation: With composite models, you can easily perform complex data manipulations and transformations. By encapsulating related data and behaviors within a composite model, you can define high-level operations that operate on the entire model as a whole. This simplifies the code required to perform common data manipulation tasks, such as filtering, sorting, aggregating, or transforming data.
  • Flexibility and dynamic composition: Composite models offer flexibility in how you structure and compose your data. You can dynamically add or remove individual models within a composite model based on your requirements. This allows you to adapt and evolve your data representation over time without impacting the overall structure of your code. It also enables you to create reusable composite models that can be composed in different ways to serve specific needs or scenarios.

By leveraging the benefits of composite models in C#, you can achieve cleaner code organization, improved data access efficiency, simplified data manipulation, and increased flexibility in representing and working with complex data structures. These advantages contribute to better code maintainability, scalability, and overall developer productivity.

Simplifying Product Catalog with Composite Models
 

Scenario and Requirement

In our scenario, we have an e-commerce application that manages a product catalog. The product catalog contains various information about products, such as their names, prices, categories, and descriptions. The goal is to simplify the representation of the product catalog using composite models.

Requirements for simplifying the product catalog representation:

1. Unified Product Representation

  • The product catalog should be represented in a unified model that encapsulates all the relevant information about each product.
  • The model should provide a convenient and intuitive way to access and manipulate product data.

2. Efficient Data Retrieval

  • Data retrieval from the product catalog should be optimized to minimize database round trips or API calls.
  • The composite model should allow fetching all necessary product data in a single query or call rather than retrieving data separately for each product.

3. Simplified Data Access

  • Accessing product information should be straightforward and require minimal code complexity.
  • The composite model should provide intuitive properties or methods to access specific product attributes.

4. Enhanced Readability and Maintainability

  • The code for working with the product catalog should be clean, readable, and maintainable.
  • The use of composite models should improve code organization and reduce the need for repetitive data retrieval and mapping logic.

By simplifying the product catalog representation with composite models, we aim to achieve a more efficient and manageable system for handling product data. In the following sections, we will demonstrate the implementation of composite models and how they address these requirements.

Step 1. Composite Model Implementation

  • To simplify the representation of the product catalog, we will define a composite model class that encapsulates the relevant product information. Here are the steps involved in implementing the composite model:
  • Create a new class to serve as the composite model for the product catalog representation. Here we have named it CompositeModel.
  • The CompositeModelclass will have properties that represent different attributes of a product, such as Name, Price, Category, Description, etc.
  • Additional properties can be added as per the specific requirements of the product catalog.

Below is the whole model which we have used for this demo.

public class Products {
  public class Electronics {
    public int ID {
      get;
      set;
    }
    public string Name {
      get;
      set;
    }
    public string Brand {
      get;
      set;
    }
    public decimal Price {
      get;
      set;
    }
    public string Description {
      get;
      set;
    }
  }

  public class Apparels {
    public int ID {
      get;
      set;
    }
    public string Name {
      get;
      set;
    }
    public string Brand {
      get;
      set;
    }
    public string Size {
      get;
      set;
    }
    public string Color {
      get;
      set;
    }
  }

  public class Furniture {
    public int ID {
      get;
      set;
    }
    public string Name {
      get;
      set;
    }
    public string Type {
      get;
      set;
    }
    public string Material {
      get;
      set;
    }
    public decimal Price {
      get;
      set;
    }
  }

  public class Accessories {
    public int ID {
      get;
      set;
    }
    public string Name {
      get;
      set;
    }
    public string Category {
      get;
      set;
    }
    public string Description {
      get;
      set;
    }
    public decimal Price {
      get;
      set;
    }
  }

  public class Vehicles {
    public int ID {
      get;
      set;
    }
    public string Brand {
      get;
      set;
    }
    public string Model {
      get;
      set;
    }
    public int Year {
      get;
      set;
    }
    public decimal Price {
      get;
      set;
    }
  }

  public class CompositeModel {
    public List < Electronics > ElectronicsList {
      get;
      set;
    }
    public List < Apparels > ApparelsList {
      get;
      set;
    }
    public List < Furniture > FurnitureList {
      get;
      set;
    }
    public List < Accessories > AccessoriesList {
      get;
      set;
    }
    public List < Vehicles > VehiclesList {
      get;
      set;
    }
  }
}

Here you can see that the composite model consists of other model lists as its properties, which makes it a nested model.

Now Identify the relevant data structures or sources that store the product information.

For each property in the CompositeModel, map it to the corresponding attribute in the related data structure. Implement the necessary logic to retrieve and populate the properties with data from the corresponding data sources.

Below is the database structure we have used for this demo.

Table Name Columns' Name Data Type
Accessories ID, Name, Category, Description, Price int, varchar, varchar, varchar, decimal
Apparels ID, Name, Brand, Size, Color int, varchar, varchar, varchar, varchar
Electronics ID, Name, Brand, Price, Description int, varchar, varchar, decimal, varchar
Furniture ID, Name, Type, Material, Price int, varchar, varchar, varchar, decimal
Vehicles ID, Brand, Model, Year, Price int, varchar, varchar, int, decimal

From this, you can see that we have model properties exactly the same as the table columns for each table in their respective model classes.

By defining the composite model class and mapping its properties to the related data structures, we establish the foundation for simplifying the representation of the product catalog. The composite model acts as a unified entity that encapsulates the relevant product information, providing a streamlined and intuitive way to access and work with the product catalog data. In the next steps, we will populate the composite model with data and leverage its benefits in accessing and manipulating the product catalog.

Step 2. Populating the Composite Model

Now we will create an API endpoint to establish a connection between our UI and database,

After that, we will be able to consume and use this composite model without any issues.

[HttpGet]
[Route("ReadAllProducts")]
public async Task<IActionResult> ReadAllProducts()
{
  try
  {
    string connectionString = _configuration.GetConnectionString("Default");
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
      string storedProcedureName = "GetAllProducts";
      var productsJson = await connection.QueryFirstOrDefaultAsync<string> 
      (storedProcedureName,commandType: CommandType.StoredProcedure);
      var result = JsonConvert.DeserializeObject<CompositeModel>(productsJson);
      return Ok(result);
    }
   }
   catch (Exception ex)
   {
     return BadRequest(ex.Message);
   }
}

The returned response will be used on the user interface to represent data. 

Step 3. Utilizing the Composite Model

For the client side, we have used razor pages; first, let's create the code behind the page in which we will call this endpoint and bind the fetched data to an object of class CompositeModel.

namespace CompositeModelUI.Pages
{
    public partial class index:ComponentBase
   {
       [Inject] HttpClient HttpClient { get; set; }
        public CompositeModel products = new();
        protected override async Task OnInitializedAsync()
        {
            var resp = await HttpClient.GetAsync("https://localhost:7267/ReadAllProducts");
            var content = await resp.Content.ReadFromJsonAsync<CompositeModel>();
            products = content;
            StateHasChanged();
        }
    }
}

Now we can move forward.

Step 4. Bind the list to HTML/C# code

After this, we can bind this list in our HTML/C# code for the rendering of data from the composite model. Here is the razor page we have used:

@page "/"
@inherits index
<PageTitle>Product details</PageTitle>
<div class="h1">Product details</div>
<table class="table table-bordered table-striped">
   <thead>
      <tr>
         <th>ID</th>
         <th>Name</th>
         <th>Specifications</th>
         <th>Category</th>
         <th>Price</th>
      </tr>
   </thead>
   <tbody>
      @if(products.ElectronicsList!=null){
      @foreach (var electronics in products.ElectronicsList)
      {
      <tr>
         <td>@electronics.ID</td>
         <td>@electronics.Brand</td>
         <td>@electronics.Description</td>
         <td>@electronics.Name</td>
         <td>@electronics.Price</td>
      </tr>
      }
      @foreach (var apparels in products.ApparelsList)
      {
      <tr>
         <td>@apparels.ID</td>
         <td>@apparels.Brand</td>
         <td>@apparels.Size</td>
         <td>@apparels.Name</td>
         <td>@apparels.Color</td>
      </tr>
      }
      @foreach (var furniture in products.FurnitureList)
      {
      <tr>
         <td>@furniture.ID</td>
         <td>@furniture.Type</td>
         <td>@furniture.Material</td>
         <td>@furniture.Name</td>
         <td>@furniture.Price</td>
      </tr>
      }
      @foreach (var accessories in products.AccessoriesList)
      {
      <tr>
         <td>@accessories.ID</td>
         <td>@accessories.Description</td>
         <td>@accessories.Category</td>
         <td>@accessories.Name</td>
         <td>@accessories.Price</td>
      </tr>
      }
      @foreach (var vehicles in products.VehiclesList)
      {
      <tr>
         <td>@vehicles.ID</td>
         <td>@vehicles.Brand</td>
         <td>@vehicles.Year</td>
         <td>@vehicles.Model</td>
         <td>@vehicles.Price</td>
      </tr>
      }
      }          
   </tbody>
</table>

Now you can run the application, and the output will look something like this.

Output

Real-World Use Cases

Imagine you're building a robust data representation system in C#. By harnessing the power of composite models, you can create an efficient and dynamic way to handle data. Let's take a closer look at how composite models can revolutionize your data representation game.

For example, consider a scenario where you have a complex customer object with various attributes such as name, address, and contact information. Rather than managing these attributes individually, a composite model allows you to encapsulate all these properties into a single object, simplifying your code and improving maintainability. It's like organizing all the pieces of a puzzle into a neat, unified picture.

Composite models make it easy to connect different objects, like customers and orders, and create a structure that reflects real-world interactions. It's like connecting the dots to tell a story. Additionally, composite models offer flexibility for manipulating data. If you need to add more features or change how the data is organized, you can do so without impacting other parts of your code. It's similar to building new things with a LEGO set by combining existing pieces.

Conclusion

Composite models in C# offer simplified data representation, streamlined data access, and improved code organization. Embracing composite models enhances code maintainability and provides flexibility for dynamic data handling. Consider using composite models to simplify data representation and unlock their benefits in your software projects. Experience the impact of composite models on code organization, maintenance, and flexibility, leading to cleaner and more efficient applications. Harness the power of composite models and transform your data-driven software development endeavors.