ServiceStack.OrmLite's SqlExpression<T> class provides several join methods like Join, LeftJoin, RightJoin, etc., but does not include a LeftOuterJoin implementation. This extension provides that functionality.
using YourNamespace;
// Join Patient with PatientDetails
var query = db.From<Patient>()
.LeftOuterJoin<Patient, PatientDetails>((p, d) => p.Id == d.PatientId);
// Produces SQL like:
// SELECT * FROM Patient
// LEFT OUTER JOIN PatientDetails ON (Patient.Id = PatientDetails.PatientId)var options = new TableOptions { Alias = "details" };
var query = db.From<Patient>()
.LeftOuterJoin<Patient, PatientDetails>(
(p, d) => p.Id == d.PatientId,
options
);
// Produces SQL like:
// SELECT * FROM Patient
// LEFT OUTER JOIN PatientDetails AS details ON (Patient.Id = details.PatientId)When you need to join using a different source table than the main table:
var query = db.From<Patient>()
.Join<Doctor>((p, d) => p.DoctorId == d.Id)
.LeftOuterJoin<Patient, Doctor, DoctorGroup>(
(d, g) => d.GroupId == g.Id
);
// Produces SQL like:
// SELECT * FROM Patient
// INNER JOIN Doctor ON (Patient.DoctorId = Doctor.Id)
// LEFT OUTER JOIN DoctorGroup ON (Doctor.GroupId = DoctorGroup.Id)While OrmLite's LeftJoin method works similarly, using LeftOuterJoin makes your code more explicit and matches the actual SQL being generated. This is especially helpful when:
- Porting SQL queries that explicitly use
LEFT OUTER JOIN - Making code more readable and self-documenting
- Maintaining consistency with database-specific optimizations that might treat
LEFT OUTER JOINdifferently
The extension methods work by:
- Getting the target table name using OrmLite's metadata
- Converting the join expression to SQL
- Constructing a raw SQL LEFT OUTER JOIN clause
- Using
CustomJointo apply the join
This ensures that the generated SQL exactly matches what you'd write by hand, while maintaining all the benefits of OrmLite's fluent interface and type safety.