Navigation Properties
Navigation properties in the Entity Data Model are shortcut properties used to locate the entities at the ends of an association. Navigation properties let you navigate from one entity to another or from one entity to related entities through an association set. Navigation properties can be used in Entity SQL queries as well as LINQ to Entities queries. They let you access related entities without having to perform a JOIN operation. For more information, see Navigation Properties (EDM).
The following example in method-based query syntax uses the SelectMany method to get all the orders of the contacts whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact.
Using AWEntities As New AdventureWorksEntities
Dim ordersQuery = AWEntities.Contact _
.Where(Function(c) c.LastName = "Zhou") _
.SelectMany(Function(o) o.SalesOrderHeader)
For Each order In ordersQuery
Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", _
order.SalesOrderID, order.OrderDate, order.TotalDue)
Next
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
IQueryable<SalesOrderHeader> ordersQuery = AWEntities.Contact
.Where(c => c.LastName == "Zhou")
.SelectMany(c => c.SalesOrderHeader);
foreach (var order in ordersQuery)
{
Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
order.SalesOrderID, order.OrderDate, order.TotalDue);
}
}
Navigation properties also appear on instances of entities in the CLR, allowing you to load related entities by calling the Load method. When you load an entity in the CLR, you should explicitly load navigation properties before accessing the entity's members. Loading these properties avoids unexpected round trips to the data source. LINQ to Entities queries are evaluated in the data source, however, so no additional round trips are necessary and the property acts as a placeholder for a more complex navigation expression.
You can explicitly load navigation properties inside of a foreach/For Each loop if MultipleActiveResultSets=True is set in the connection string. If the connection string contains MultipleActiveResultSets=False, the Load method call in the following example will throw an EntityCommandExecutionException.
Using AWEntities As New AdventureWorksEntities()
Dim contacts = _
AWEntities.Contact _
.Where(Function(c) c.LastName = "Johnson") _
.Select(Function(c) c)
Try
For Each contact As Contact In contacts
Console.WriteLine("Name: {0}, {1}", contact.LastName, contact.FirstName)
' Throws a EntityCommandExecutionException if
' MultipleActiveResultSets is set to False in the
' connection string.
contact.SalesOrderHeader.Load()
For Each order As SalesOrderHeader In contact.SalesOrderHeader
Console.WriteLine("Order ID: {0}", order.SalesOrderID)
Next
Next
Catch ex As EntityCommandExecutionException
Console.WriteLine(ex.InnerException)
End Try
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
IQueryable<Contact> contacts =
AWEntities.Contact
.Where(c => c.LastName == "Johnson")
.Select(c => c);
try
{
foreach (Contact contact in contacts)
{
Console.WriteLine("Name: {0}, {1}", contact.LastName, contact.FirstName);
// Throws a EntityCommandExecutionException if
// MultipleActiveResultSets is set to False in the
// connection string.
contact.SalesOrderHeader.Load();
foreach (SalesOrderHeader order in contact.SalesOrderHeader)
{
Console.WriteLine("Order ID: {0}", order.SalesOrderID);
}
}
}
catch (EntityCommandExecutionException ex)
{
Console.WriteLine(ex.InnerException);
}
}
See Also
Concepts
Method-Based Query Syntax Examples: Navigating Relationships (LINQ to Entities)
Expressions in LINQ to Entities Queries