When the default database dialect is insufficient to cover the target database version or special SQL behavior, you can extend LiteOrm by creating a custom SqlBuilder.
| Extension Point | Purpose |
|---|---|
BuildSelectSql |
Customize the final assembly of query statements. |
RegisterFunctionSqlHandler |
Register custom SQL function translations. |
DataSource-level RegisterSqlBuilder(...) |
Bind custom dialect to a specified data source. |
Oracle 11g doesn’t support modern LIMIT/OFFSET syntax. You can inherit from OracleBuilder and override the paging logic:
public class Oracle11gBuilder : OracleBuilder
{
public readonly static new Oracle11gBuilder Instance = new Oracle11gBuilder();
public override void BuildSelectSql(ref SqlValueStringBuilder subSelect, ref ValueStringBuilder result)
{
// Use ROW_NUMBER() OVER(...) for paging
}
}
For a complete implementation, see Custom Paging.
builder.Host.RegisterLiteOrm(options =>
{
options.RegisterSqlBuilder("LegacyOracle", Oracle11gBuilder.Instance);
});
builder.Host.RegisterLiteOrm(options =>
{
options.RegisterSqlBuilder(typeof(OracleConnection), Oracle11gBuilder.Instance);
});
// 1. Write custom dialect
public sealed class LegacyOracleBuilder : OracleBuilder
{
public static readonly LegacyOracleBuilder Instance = new LegacyOracleBuilder();
}
// 2. Register at startup
builder.Host.RegisterLiteOrm(options =>
{
options.RegisterSqlBuilder("LegacyOracle", LegacyOracleBuilder.Instance);
});
// 3. Point entity or data source to corresponding database in configuration
[Table("Users", DataSource = "LegacyOracle")]
public class User
{
}
// 4. Business layer continues querying in a unified way
var users = await userService.SearchAsync(q => q.Where(u => u.Age >= 18).Skip(0).Take(20));
This pattern is suitable for encapsulating compatibility logic in the infrastructure layer, so business code doesn’t need to be aware of database version differences.
using static LiteOrm.Common.Expr;
MySqlBuilder.Instance.RegisterFunctionSqlHandler("DATE_FORMAT", (ref outSql, expr, context, sqlBuilder, outputParams) =>
{
outSql.Append("DATE_FORMAT(");
Args[0].ToSql(ref outSql, context, sqlBuilder, outputParams);
outSql.Append(", ");
Args[1].ToSql(ref outSql, context, sqlBuilder, outputParams);
outSql.Append(')');
});
If the function comes from Lambda or member extensions, you also need to register the corresponding conversion logic in LambdaExprConverter. See Expression Extension.