Generated code - QuerySpec, Joins.

Specifying joins is a key element of the QuerySpec API. It allows to specify joins with both EntityRelation objects, which are created using the generated code, as well as using extension methods. One can mix them to build joins.

Joins have to be specified inside a call to .From(). For DynamicQuery instances, this is straight forward. For EntityQuery<T> instances, this needs a construct called QueryTarget:

var q = qf.Customer
	.From(QueryTarget.InnerJoin(qf.Order).On(CustomerFields.CustomerId==OrderFields.OrderId))


QueryTarget is only needed for EntityQuery<T> instances. DynamicQueries don't have a natural source, so in these cases, one always has to specify the full left operand. Using QueryTarget will lead to an error.

note Note:
Calling .From() multiple times will overwrite the From clause of the previous call, so specify all joins with one .From() call.

Method based join building

The methods .InnerJoin(), .LeftJoin(), .RightJoin(), .FullJoin() and .CrossJoin() can be called inside a From() call on an EntityQuery<T> to join that entity query with a related element, which can be another query.

There are also overloads which accept an EntityRelation object. This can have the advantage where the user doesn't want to fill in the On clause, as that's already specified by the EntityRelation object. When an EntityRelation object is specified, the start entity has to match the T type of the EntityQuery<T>. The method called decides which JoinHint is used when adding the EntityRelation to the overall RelationCollection.

Examples:
var qf = new QueryFactory(); 
// using a related element query and an On() clause. 
var q = qf.Employee 
	.From(QueryTarget 
		.LeftJoin(qf.Order).On(EmployeeFields.EmployeeId==OrderFields.EmployeeId));
		
// using an EntityRelation object
var q2 = qf.Employee
	.From(QueryTarget.InnerJoin(EmployeeEntity.Relations.OrderEntityUsingEmployeeId));


With a DynamicQuery, QueryTarget can't be used. Calling the join methods on a dynamic query like:

// Incorrect
var qf = new QueryFactory(); 
var q = qf.Create() 
	.From(QueryTarget.InnerJoin(qf.Order).On(some predicate)); 


This is not correct, although the api allows it, because a dynamic query doesn't have a default source. Instead, use the From() method for dynamic queries:

// correct 
var qf = new QueryFactory(); 
var q = qf.Create() 
	.From(qf.Customer 
		.InnerJoin(qf.Order).On(CustomerFields.CustomerId==OrderFields.CustomerId));


For dynamic queries, to start a join with an EntityRelation object and pass it to the From() method, use Joins.joinmethod. For example, to create an Inner join using the join above but with entityrelation objects, one should use:

// correct 
var qf = new QueryFactory(); 
var q = qf.Create() 
	.From(Joins.Inner(CustomerEntity.Relations.OrderEntityUsingCustomerId));


As the .InnerJoin etc. methods work on an IJoinOperand object, this code compiles:

// Incorrect
var qf = new QueryFactory(); 
// using a related element query and an On() clause. 
var q = qf.Employee.LeftJoin(qf.Order).On(EmployeeFields.EmployeeId==OrderFields.EmployeeId));


However, this isn't correct as 'q' now is an InnerOuterJoin object, not a query.


LLBLGen Pro Runtime Framework v4.1 documentation. ©2013 Solutions Design bv