Loading related entities

A relational database is named so because it makes the relationship between entities (Tables) a first-class citizen and gives means to validate and query those relationships (that is, foreign key constraints and joins). 

The power of EF Core as an O/RM is that it bridges the world of object-oriented class associations and the world of relational database joins. It does so by treating the class properties that reference another entity (or a collection of entities) as a Navigation Property. With a Navigation Property, each operation you do on the property will generate the equivalent SQL join statement. For example, GiveNTake allows its users to search for products in a specific category. This is what it looks like:

var products = await _context.Products
.Where(p => p.Category.ParentCategory.Name == category)
.ToListAsync();

The preceding code uses the Where operator to filter the products, but it doesn't check the product's simple values. Instead, it checks the parent category to which the products category belongs, all by simply using the navigation properties. If you're curious what SQL was used behind the scenes, here is the generated SQL statement that this code produces, which shows how the EF Core engine intelligently generates two JOIN clauses:

SELECT [p].[ProductId], [p].[CategoryId], [p].[CityId], [p].[Description], [p].[OwnerUserId], [p].[PublishDate], [p].[Title]
FROM [Products] AS [p]
INNER JOIN [Categories] AS [p.Category] ON [p].[CategoryId] = [p.Category].[Id]
LEFT JOIN [Categories] AS [p.Category.ParentCategory] ON [p.Category].[ParentCategoryId] =
[p.Category.ParentCategory].[Id]
WHERE [p.Category.ParentCategory].[Name] = @__category_0

Running queries that use the navigation properties will do everything as expected on the database side, but the result that you get might be confusing because you might expect the objects that the navigation properties refer to be included as well, but you'll find them missing. Before EF Core, Entity Framework included a feature called Lazy Loading, where a referenced object would be loaded from the database automatically the first time you used the navigation property; however, EF Core doesn't include this feature at the time of writing this book. Instead, you must explicitly tell EF Core to load related entities before you execute your query by using the Include and ThenInclude operators. For example, if you wish the query we used in the preceding code to include the category and subcategory of the products it retrieves, this is how you'll write it:

var products = await _context.Products
.Include(product => product.Category)
.ThenInclude(category => category.ParentCategory);
.Where(p => p.Category.ParentCategory.Name == category)
.ToListAsync();

This query will result in the products and will include all the categories that are referenced by them (note that if a category is referenced by multiple products, it will only be retrieved once, and the same object will be used by all products).

Include will work only if the type of the result that the query retrieved is the same as the type that the Include was applied on, so if you use the Select operator in your query, the Include might not work.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.37.20