Navigation Properties
Load related entities with the query, through the navigation property enums.
On this page
What Are Navigation Properties?#
Navigation Properties(or Nav Props) are C# representations of Foreign Keys between tables in a database.
They represent parent child relationships between the entities.
For example a Customer might have a Nav Prop called Orders. That represent the orders belonging to the customer
When The Sharp Factory App generates the C# code in your solution; it will automatically generate Nav Props in your entities.
These Nav Props are actual strongly types properties. They can be a single object or a list of objects depending on the relationship of the entities.
Navigation Property Container#
When The Sharp Factory App generates the C# code in your solution, amongst other things, it generates a navigation property container class for each entity that has navigation properties, with one static field per navigation property.
The naming convention is EntityName + NavProperty. For example an Entity called Customer will have a corresponding class called CustomerNavProperty, and CustomerNavProperty.Orders is a NavProp<CustomerProperty, OrderProperty>: a navigation property of the customer that leads to its orders.
Navigation Properties And Query#
To craft your Query to populate navigation properties of your entities.
Start by creating an instance of the Query class with the entity's property container, as for any query. Then add the navigation properties with Append, between BeginNavProps and EndNavProps, or inside NavProps in builder syntax.
Only queries on entities that have navigation properties have these methods: on other entities they do not compile.
The following code illustrates how to pull a list of customers along with their orders
Fluent Syntax#
// create an instance of the Repository Container// remember this can be a singleton if you// declare it early on and reuse it for the// lifetime of your applicationvar repo = new RepositoryContainer();// create an instance of Query and// specify the entity's property containervar query = new Query<CustomerProperty>() .BeginNavProps() .Append(CustomerNavProperty.Orders) .EndNavProps();// pass the query to one of the repository methods// in this case the ToList on the Customer repositoryvar result = repo.AppDb.Sales.Customer.ToList(query);// iterate over the customersforeach (var customer in result){ // get the orders from the navigation property var orders = customer.Orders; // do something with the orders here}Builder Syntax#
// create an instance of the Repository Container// remember this can be a singleton if you// declare it early on and reuse it for the// lifetime of your applicationvar repo = new RepositoryContainer();// create an instance of Query and// specify the entity's property containervar query = new Query<CustomerProperty>() .Builder(builder => { builder .NavProps((navProps) => { navProps .Append(CustomerNavProperty.Orders); }); });// pass the query to one of the repository methods// in this case the ToList on the Customer repositoryvar result = repo.AppDb.Sales.Customer.ToList(query);// iterate over the customersforeach (var customer in result){ // get the orders from the navigation property var orders = customer.Orders; // do something with the orders here}The previous examples are equivalent. The only difference is the syntax.
Nested Navigation Properties#
To also load the navigation properties of the related entities, continue with Then.
It takes a navigation property of the entity the previous one leads to: after CustomerNavProperty.Orders it takes a field of OrderNavProperty, and anything else does not compile.
Call Append again to add another navigation property of the customer.
The following code pulls a list of customers with their orders, the lines of each order, and the customers' addresses.
Fluent Syntax#
// create an instance of the Repository Container// remember this can be a singleton if you// declare it early on and reuse it for the// lifetime of your applicationvar repo = new RepositoryContainer();// Orders, then each order's Lines, then the Addressesvar query = new Query<CustomerProperty>() .BeginNavProps() .Append(CustomerNavProperty.Orders).Then(OrderNavProperty.Lines) .Append(CustomerNavProperty.Addresses) .EndNavProps();var result = repo.AppDb.Sales.Customer.ToList(query);foreach (var customer in result){ foreach (var order in customer.Orders) { // the lines of the order are loaded too var lines = order.Lines; }}Builder Syntax#
// create an instance of the Repository Container// remember this can be a singleton if you// declare it early on and reuse it for the// lifetime of your applicationvar repo = new RepositoryContainer();// Orders, then each order's Lines, then the Addressesvar query = new Query<CustomerProperty>() .Builder(builder => { builder .NavProps((navProps) => { navProps .Append(CustomerNavProperty.Orders).Then(OrderNavProperty.Lines) .Append(CustomerNavProperty.Addresses); }); });var result = repo.AppDb.Sales.Customer.ToList(query);By Primary Key With Navigation Properties#
The ByPK method of an entity with navigation properties has an overload that takes a NavProps collection, for example NavProps<CustomerProperty>, to load one entity with its related entities.
// create an instance of the Repository Container// remember this can be a singleton if you// declare it early on and reuse it for the// lifetime of your applicationvar repo = new RepositoryContainer();// the navigation properties to loadvar navProps = new NavProps<CustomerProperty>();navProps.Add(CustomerNavProperty.Orders);// the customer with primary key 123, with its ordersvar customer = repo.AppDb.Sales.Customer.ByPK(123, navProps);