Search code examples
azure-service-fabric

Reliable Service Data Model Issue


I'm new to Azure Service Fabric, and watched Ivan Gavryliuk's "Understanding the Programming Models of Azure Service Fabric" course on Pluralsight. I've been following along and the basic data model in the reliable service and API work as explained in the course.

However, if I increase the complexity of the data model used I hit an error.

Product.cs from the ECommerce.ProductCatelog.Model

namespace ECommerce.ProductCatalog.Model
{
   public class Product
   {
      public Guid Id { get; set; }

      public string Name { get; set; }

      public string Description { get; set; }

      public double Price { get; set; }

      public int Availability { get; set; }
      public Supplier Suppliers { get; set; }
   }

   public class Supplier
   {
      public Guid Id { get; set; }
      public string Name { get; set; }

   }
}

ApiProduct.cs from ECommerce.API.Model

   public class ApiProduct
   {
      [JsonProperty("id")]
      public Guid Id { get; set; }

      [JsonProperty("name")]
      public string Name { get; set; }

      [JsonProperty("description")]
      public string Description { get; set; }

      [JsonProperty("price")]
      public double Price { get; set; }

      [JsonProperty("isAvailable")]
      public bool IsAvailable { get; set; }

      [JsonProperty("suppliers")]
      public ApiSupplier suppliers { get; set; }

   }

   public class ApiSupplier
   {
      [JsonProperty("id")]
      public Guid Id { get; set; }

      [JsonProperty("name")]
      public string Name { get; set; }

   }

ProductController.cs from Ecommerce.API.Controlers

[HttpGet]
      public async Task<IEnumerable<ApiProduct>> GetAsync()
      {
         IEnumerable<Product> allProducts = await _service.GetAllProductsAsync();

         return allProducts.Select(p => new ApiProduct
         {
            Id = p.Id,
            Name = p.Name,
            Description = p.Description,
            Price = p.Price,
            IsAvailable = p.Availability > 0,
            suppliers = p.Suppliers
         });
      }

The last line in the above block triggers an intellisense error: "Cannot implicitly convert type 'ECommerce.ProductCatelog.Model.Supplier' to 'ECommerce.API.Model.Supplier'"

Any suggestions on how to work around this welcome :)

Cheers, Adam


Solution

  • Your problem is not specific to Service Fabric but C# in general. You are trying to set a variable with a value of a different type.

    In this line:

    IEnumerable<Product> allProducts = await _service.GetAllProductsAsync();
    

    You get a collection of items of type ECommerce.ProductCatalog.Model.Product. In this class, you added the property Suppliers (which should be Supplier since it's not a collection) of type ECommerce.ProductCatalog.Model.Supplier.

    Now, with the following line:

         return allProducts.Select(p => new ApiProduct
         {
            Id = p.Id,
            Name = p.Name,
            Description = p.Description,
            Price = p.Price,
            IsAvailable = p.Availability > 0,
            suppliers = p.Suppliers
         });
    

    you are converting this collection to a collection of a new type ECommerce.API.Model.Product, to which you added a new property Suppliers of type ECommerce.API.Model.Supplier, but you set this property to the original value, without converting it. So, convert the original Suppliers property to the correct type:

         return allProducts.Select(p => new ApiProduct
         {
            Id = p.Id,
            Name = p.Name,
            Description = p.Description,
            Price = p.Price,
            IsAvailable = p.Availability > 0,
            suppliers = new ApiSupplier
            {
               Id = p.Suppliers.Id,
               Name = p.Suppliers.Name
            }    
         });
    

    Update: make Suppliers a collection

    Make your Suppliers property a collection both in your data model and in your Api model:

     public Collection<ApiSupplier> suppliers { get; set; }
    

    Then convert the collection accordingly:

         return allProducts.Select(p => new ApiProduct
         {
            Id = p.Id,
            Name = p.Name,
            Description = p.Description,
            Price = p.Price,
            IsAvailable = p.Availability > 0,
            suppliers = p.Suppliers.Select(s => new ApiSupplier
               {
                 Id = s.Id,
                 Name = s.Name
               }    
         });