It depends on what you actually want to do within your view: A view model is supposed to contain exactly the data necessary to display the view. Usually, you would not want to include more data there. So using database models inside of a view model is not the best choice; it would be better to design actual view models that match the stuff you display, and then you decide how to properly get that data.
From how your view model looks, I could assume two use cases:
- You want to display a set of products, and list those product types that that set of products have.
- You want to display a set of products, and a list of all product types.
Option 2 is really simple and requires you to only query each entity type once:
var viewModel = new ProductsViewModel
{
Products = await db.Products.ToListAsync(),
ProductTypes = await db.ProductTypes.ToListAsync(),
};
Option 1 can be solved naively by including the product types through the navigation property in the Product
entity:
var products = await db.Products.Include(p => p.ProductType).ToListAsync();
var viewModel = new ProductsViewModel
{
Products = products,
ProductTypes = products.Select(p => p.ProductType).Distinct().ToList(),
};
This however has the downside that with few distinct product types you will be loading each product type multiple times. Because your product type has only an id and a name, this is not that problematic but for more complex types it can be.
A different approach would be to query the product type ids first from the list of products, and then loading the product types afterwards:
var products = await db.Products.Include(p => p.ProductType).ToListAsync();
var productTypeIds = product.Select(p => p.ProductTypeId).Distinct().ToList();
var viewModel = new ProductsViewModel
{
Products = products,
ProductTypes = await db.ProductTypes.Select(t => productTypeIds.Contains(t.Id)).ToListAsync(),
};
Two notes:
- I ignored the existence of your repository here and just assumed that you are using an EntityFramework
DbContext
here. If you want to abstract that into a repository, you can do so.
- The entity is named
Products
but only contains information about a single product. Similarly, the view model contains a property Products
of that exact same type. That does not make a lot of sense to me, so I just assumed that the entity is called Product
and represents a single item, while the ProductsViewModel
has Products
, a list of Product
.