Reputation: 39
I have a product table and a category table. Where all the products have a FK-categoryId. How to stop loading data multiple times? Like this:
Class:
public partial class Product
{
public Product()
{
OrderItem = new HashSet<OrderItem>();
ProductPictureMapping = new HashSet<ProductPictureMapping>();
}
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public partial class Category
{
public Category()
{
Product = new HashSet<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Product { get; set; }
}
Controller method:
var allProduct = _context.Product
.Include("Category")
.ToListAsync();
Output:
It returns a Product then a Category then all Product under Category Note that I already disable looping using this in startup.csNewtonsoft.Json.ReferenceLoopHandling.Ignore;
[{
"id": 1,
"name": "Redmi Note 7",
"category": {
"id": 2,
"name": "Mobile",
"product": [
{
"id": 2,
"name": "Mi Note 9",
"category":null
}]
},
{
"id": 2,
"name": "Mi Note 9",
"category": {
"id": 1,
"name": "Redmi Note 7",
"category":null
}
}]
Upvotes: 0
Views: 274
Reputation: 8338
You can use Data Transfer Object (DTO)
models to get rid of the navigation properties which create those reference loops.
Create the following two DTO models -
public class ProductDTO
{
public int Id { get; set; }
public string Name { get; set; }
public CategoryDTO Category { get; set; }
}
public class CategoryDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
Then use projection in your query like -
var allProduct = dbCtx.Products
.Select(p => new ProductDTO
{
Id = p.Id,
Name = p.Name,
Category = new CategoryDTO
{
Id = p.Category.Id,
Name = p.Category.Name
}
});
If you don't need typed objects in your query result, you can do the same thing without creating any DTO models and using anonymous types in your projection like -
var allProduct = dbCtx.Products
.Select(p => new
{
Id = p.Id,
Name = p.Name,
Category = new
{
Id = p.Category.Id,
Name = p.Category.Name
}
});
Upvotes: 1