Home > database >  Nullable reference type when using DTO classes
Nullable reference type when using DTO classes

Time:03-08

Product

        public int Id { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public Category Category {get; set;}

Category

        public int Id { get; set; }
        public string CategoryName { get; set; }
        public string CategoryDescription { get; set; }
        public Product Product{get; set;}

ProductViewModel

    public int Id { get; set; }
    public string ProductName { get; set; }
    public string ProductDescription { get; set; }
    public Category Category {get; set;}

Controller

     public IActionResult GetProducts()
     {
        using var dbContext = new DatabaseContext();
        var result = dbContext.Products.Where(i => i.Id == id)
                                 .ThenInclude(i => i.Category)
                                 .ToList();
        List<ProductViewModel> productList = new List<ProductViewModel>();
        foreach(var item in result)
        {
         var model = ProductViewModel()
         {
             Id = item.Id,
             ProductName = item.ProductName,
             ProductDescription = item.ProductDescription,
             Category = new Category()
             { 

             // Error: item.Category.CategoryName = 'item.Category.CategoryName' threw an 
                 exception of type 'System.NullReferenceException'

             CategoryName= item.Category.CategoryName, 
             CategoryDescription = item.Category.CategoryDescription, 
             Id = item.Category.Id 
             }
          productList.Add(model); 
         }
     }

How can I ignore null values in my DTO class.

I get my products from database. Since the category is null in some products, I get an error when mapping it to my DTO class.

CodePudding user response:

Use Select for projecting Model to DTO. It will create optimal SQL and should avoid loading unwanted data into the memory. Also EF should resolve nullability automatically.

public IActionResult GetProducts()
{
    using var dbContext = new DatabaseContext();

    var productList = dbContext.Products
        .Where(i => i.Id == id)
        .Select(item => new ProductViewModel
        {
            Id = item.Id,
            ProductName = item.ProductName,
            ProductDescription = item.ProductDescription,
            Category = new Category
            { 
                CategoryName = item.Category.CategoryName, 
                CategoryDescription = item.Category.CategoryDescription, 
                Id = item.Category.Id 
            }
        })
        .ToList();
    ...
}

CodePudding user response:

Answer of @Svyatoslav Danyliv is the clean solution to your problem! However below my guess to your exception in your current solution.

I think it is because you are using ThenInclude. ThenInclude is usually used when you need to go into deeper includes.

Example: human --> head --> eye

dbContext.Humans.Include(x => x.Head).ThenInclude(x => x.Eye);

Your adjusted code:

var result = dbContext.Products.Include(i => i.Category).Where(i => i.Id == id).ToList();

Change ThenInclude with Include and give it a try! :)

  • Related