C
C#8mo ago
Cosen

✅ EntityFramework: Navigation property makes a nested object call

So i have transports and categories models/tables , both are connected with a relationship , one category can have many transports and vice versa. Here is my code: Category model:
public class Categories
{
[Key]
public int category_id { get; set; }
public string name { get; set; }
// category can have many transports
public ICollection<Transports> Transports { get; set; }
}
public class Categories
{
[Key]
public int category_id { get; set; }
public string name { get; set; }
// category can have many transports
public ICollection<Transports> Transports { get; set; }
}
Transport model:
public class Transports
{
[Key]
public int transport_id { get; set; }
public int category_id { get; set; }
public Categories Category { get; set; }
public string name { get; set; }
}
public class Transports
{
[Key]
public int transport_id { get; set; }
public int category_id { get; set; }
public Categories Category { get; set; }
public string name { get; set; }
}
The problem is i get this schema in swagger api call:
{
"transport_id": 0,
"category_id": 0,
"categories": {
"category_id": 0,
"name": "string",
"transports": [
"string"
]
},
"name": "string"
}
]
{
"transport_id": 0,
"category_id": 0,
"categories": {
"category_id": 0,
"name": "string",
"transports": [
"string"
]
},
"name": "string"
}
]
My category table tries to call another value called "transports" , which i think is from the navigation property in categories model:
"categories": {
"category_id": 0,
"name": "string",
"transports": [
"string"
]
},
"categories": {
"category_id": 0,
"name": "string",
"transports": [
"string"
]
},
The problem fixes itself if i add [JsonIgnore] in my categories model above the navigation line:
// category can have many transports
[JsonIgnore]
public ICollection<Transports> Transports { get; set; }
// category can have many transports
[JsonIgnore]
public ICollection<Transports> Transports { get; set; }
but it seems this is a bad practice: I have tried to dto my Transport model:
public class TransportsDto
{
public int transport_id { get; set }
public int category_id { get; set; }
public string name { get; set; }


}
public class TransportsDto
{
public int transport_id { get; set }
public int category_id { get; set; }
public string name { get; set; }


}
but this way it does not return the relationships with category table. I am kinda lost here , what am i doing wrong?
3 Replies
Cosen
Cosen8mo ago
i am also using dto when returning a single category : (not sure if this even matters here)
public class CategoriesDto
{
public int category_id { get; set; }

public string name { get; set; }

}
public class CategoriesDto
{
public int category_id { get; set; }

public string name { get; set; }

}
Patrick
Patrick8mo ago
swagger shouldn't know about your EF models your DTOs are projections, the thing you want to expose to people using your software
public class CategoryDto
{
public string Name { get; set; }
public List<TransportDto> Transports { get; set; }
}

public class TransportDto
{
public string Name { get; set; }
}
public class CategoryDto
{
public string Name { get; set; }
public List<TransportDto> Transports { get; set; }
}

public class TransportDto
{
public string Name { get; set; }
}
var categories = await db.Categories
.Select(x => new CategoryDto
{
Name = x.Name,
Transports = x.Transports.Select(d => new TransportDto { Name = d.Name }).ToList();
})
.ToListAsync();

return categories;
var categories = await db.Categories
.Select(x => new CategoryDto
{
Name = x.Name,
Transports = x.Transports.Select(d => new TransportDto { Name = d.Name }).ToList();
})
.ToListAsync();

return categories;
Cosen
Cosen8mo ago
thanks this actually worked! I made changes to my transport dto and included
public CategoriesDto categories { get; set; }
public CategoriesDto categories { get; set; }
So my final transport dto is
public class TransportsDto
{
public int transport_id { get; set }
public int category_id { get; set; }
public CategoriesDto categories { get; set; }
public string name { get; set; }
public class TransportsDto
{
public int transport_id { get; set }
public int category_id { get; set; }
public CategoriesDto categories { get; set; }
public string name { get; set; }