Reputation: 3
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.
Upvotes: 0
Views: 849
Reputation: 1035
Hello you can try using ??= operator which can protects you from null reference exception
using var dbContext = new A1APPsContext();
var result = dbContext.Products.Where(i => i.Id == id)
.Include(i => i.Category)
.ToList();
List<ProductViewModel> productList = new List<ProductViewModel>();
foreach (var item in result)
{
item.Category ??= new Category();
var model = 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
}
};
productList.Add(model);
}
In that case you can also give a "No Category" category name and you will get it only when you dont have category by applying it in the class
public class Category
{
public int Id { get; set; }
public string CategoryName { get; set; } = "No Category";
public string CategoryDescription { get; set; }
public Product Product { get; set; }
}
Upvotes: 0
Reputation: 299
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! :)
Upvotes: 0
Reputation: 27282
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();
...
}
Upvotes: 1