Add scoped typed multi-table select builder

This commit is contained in:
root
2026-02-27 09:29:23 +01:00
parent 8210fbfdb5
commit 8555e1958c
8 changed files with 1706 additions and 4 deletions

View File

@@ -1977,6 +1977,17 @@ namespace DynamORM
}
return builder;
}
/// <summary>Adds to the <code>FROM</code> clause using a typed scope builder with evolving join arity.</summary>
/// <typeparam name="T">Type which can be represented in database.</typeparam>
/// <param name="alias">Table alias.</param>
/// <param name="noLock">use no lock.</param>
/// <returns>Scope builder instance.</returns>
public virtual IDynamicTypedSelectScopeQueryBuilder<T> FromTypedScope<T>(string alias = null, bool noLock = false)
{
DynamicTypedSelectQueryBuilder<T> builder = (DynamicTypedSelectQueryBuilder<T>)FromTyped<T>(alias, noLock);
string resolvedAlias = string.IsNullOrEmpty(alias) ? builder.Tables[0].Alias ?? builder.Tables[0].Name : alias;
return new DynamicTypedSelectScopeQueryBuilder<T>(builder, resolvedAlias);
}
/// <summary>Adds to the <code>FROM</code> clause using <see cref="Type"/>.</summary>
/// <param name="t">Type which can be represented in database.</param>
/// <returns>This instance to permit chaining.</returns>
@@ -7364,6 +7375,55 @@ namespace DynamORM
/// <summary>Add typed SQL DSL order-by expression using root and first four joined table contexts.</summary>
IDynamicTypedSelectQueryBuilder<T> OrderBySql<TJoin1, TJoin2, TJoin3, TJoin4>(Func<TypedTableContext<T>, TypedTableContext<TJoin1>, TypedTableContext<TJoin2>, TypedTableContext<TJoin3>, TypedTableContext<TJoin4>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T>, TypedTableContext<TJoin1>, TypedTableContext<TJoin2>, TypedTableContext<TJoin3>, TypedTableContext<TJoin4>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed scope-based select builder with evolving join arity.</summary>
public interface IDynamicTypedSelectScopeQueryBuilder<T> : IDynamicSelectQueryBuilder
{
IDynamicTypedSelectScopeQueryBuilder<T, TJoin1> Join<TJoin1>(Func<TypedScopeJoinBuilder<T, TJoin1>, TypedScopeJoinBuilder<T, TJoin1>> specification);
IDynamicTypedSelectScopeQueryBuilder<T> SelectSql(Func<TypedTableContext<T>, TypedSqlSelectable> selector, params Func<TypedTableContext<T>, TypedSqlSelectable>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T> WhereSql(Func<TypedTableContext<T>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T> HavingSql(Func<TypedTableContext<T>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T> GroupBySql(Func<TypedTableContext<T>, TypedSqlExpression> selector, params Func<TypedTableContext<T>, TypedSqlExpression>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T> OrderBySql(Func<TypedTableContext<T>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed scope-based select builder with two typed table contexts.</summary>
public interface IDynamicTypedSelectScopeQueryBuilder<T1, T2> : IDynamicSelectQueryBuilder
{
IDynamicTypedSelectScopeQueryBuilder<T1, T2, TJoin3> Join<TJoin3>(Func<TypedScopeJoinBuilder<T1, T2, TJoin3>, TypedScopeJoinBuilder<T1, T2, TJoin3>> specification);
IDynamicTypedSelectScopeQueryBuilder<T1, T2> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlSelectable>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlExpression>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed scope-based select builder with three typed table contexts.</summary>
public interface IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> : IDynamicSelectQueryBuilder
{
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, TJoin4> Join<TJoin4>(Func<TypedScopeJoinBuilder<T1, T2, T3, TJoin4>, TypedScopeJoinBuilder<T1, T2, T3, TJoin4>> specification);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlSelectable>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlExpression>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed scope-based select builder with four typed table contexts.</summary>
public interface IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> : IDynamicSelectQueryBuilder
{
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, TJoin5> Join<TJoin5>(Func<TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5>, TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5>> specification);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlSelectable>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlExpression>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed scope-based select builder with five typed table contexts.</summary>
public interface IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> : IDynamicSelectQueryBuilder
{
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlSelectable>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlPredicate> predicate);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlExpression>[] selectors);
IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlOrderExpression>[] selectors);
}
/// <summary>Typed update query builder for mapped entities.</summary>
/// <typeparam name="T">Mapped entity type.</typeparam>
public interface IDynamicTypedUpdateQueryBuilder<T> : IDynamicUpdateQueryBuilder
@@ -7753,6 +7813,188 @@ namespace DynamORM
return builder.Join(on, alias, DynamicJoinType.Full);
}
}
public abstract class TypedScopeJoinBuilderBase<TSelf>
where TSelf : TypedScopeJoinBuilderBase<TSelf>
{
/// <summary>Gets join alias.</summary>
public string Alias { get; private set; }
/// <summary>Gets join type.</summary>
public DynamicJoinType JoinType { get; private set; }
/// <summary>Gets custom join type text.</summary>
public string CustomJoinType { get; private set; }
/// <summary>Gets a value indicating whether joined source should use NOLOCK.</summary>
public bool UseNoLock { get; private set; }
protected TypedScopeJoinBuilderBase()
{
JoinType = DynamicJoinType.Join;
}
public TSelf As(string alias)
{
Alias = alias;
return (TSelf)this;
}
public TSelf Inner()
{
JoinType = DynamicJoinType.Inner;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf Join()
{
JoinType = DynamicJoinType.Join;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf Left()
{
JoinType = DynamicJoinType.Left;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf Right()
{
JoinType = DynamicJoinType.Right;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf Full()
{
JoinType = DynamicJoinType.Full;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf LeftOuter()
{
JoinType = DynamicJoinType.LeftOuter;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf RightOuter()
{
JoinType = DynamicJoinType.RightOuter;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf FullOuter()
{
JoinType = DynamicJoinType.FullOuter;
CustomJoinType = null;
return (TSelf)this;
}
public TSelf Type(string joinType)
{
if (string.IsNullOrEmpty(joinType))
throw new ArgumentNullException("joinType");
CustomJoinType = joinType.Trim();
return (TSelf)this;
}
public TSelf NoLock(bool use = true)
{
UseNoLock = use;
return (TSelf)this;
}
}
public sealed class TypedScopeJoinBuilder<T1, TRight> : TypedScopeJoinBuilderBase<TypedScopeJoinBuilder<T1, TRight>>
{
internal Func<TypedTableContext<T1>, TypedTableContext<TRight>, TypedSqlPredicate> OnSqlPredicate { get; private set; }
internal string OnRawCondition { get; private set; }
public TypedScopeJoinBuilder<T1, TRight> OnSql(Func<TypedTableContext<T1>, TypedTableContext<TRight>, TypedSqlPredicate> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
OnSqlPredicate = predicate;
OnRawCondition = null;
return this;
}
public TypedScopeJoinBuilder<T1, TRight> OnRaw(string condition)
{
if (string.IsNullOrEmpty(condition))
throw new ArgumentNullException("condition");
OnRawCondition = condition.Trim();
OnSqlPredicate = null;
return this;
}
}
public sealed class TypedScopeJoinBuilder<T1, T2, TRight> : TypedScopeJoinBuilderBase<TypedScopeJoinBuilder<T1, T2, TRight>>
{
internal Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<TRight>, TypedSqlPredicate> OnSqlPredicate { get; private set; }
internal string OnRawCondition { get; private set; }
public TypedScopeJoinBuilder<T1, T2, TRight> OnSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<TRight>, TypedSqlPredicate> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
OnSqlPredicate = predicate;
OnRawCondition = null;
return this;
}
public TypedScopeJoinBuilder<T1, T2, TRight> OnRaw(string condition)
{
if (string.IsNullOrEmpty(condition))
throw new ArgumentNullException("condition");
OnRawCondition = condition.Trim();
OnSqlPredicate = null;
return this;
}
}
public sealed class TypedScopeJoinBuilder<T1, T2, T3, TRight> : TypedScopeJoinBuilderBase<TypedScopeJoinBuilder<T1, T2, T3, TRight>>
{
internal Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<TRight>, TypedSqlPredicate> OnSqlPredicate { get; private set; }
internal string OnRawCondition { get; private set; }
public TypedScopeJoinBuilder<T1, T2, T3, TRight> OnSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<TRight>, TypedSqlPredicate> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
OnSqlPredicate = predicate;
OnRawCondition = null;
return this;
}
public TypedScopeJoinBuilder<T1, T2, T3, TRight> OnRaw(string condition)
{
if (string.IsNullOrEmpty(condition))
throw new ArgumentNullException("condition");
OnRawCondition = condition.Trim();
OnSqlPredicate = null;
return this;
}
}
public sealed class TypedScopeJoinBuilder<T1, T2, T3, T4, TRight> : TypedScopeJoinBuilderBase<TypedScopeJoinBuilder<T1, T2, T3, T4, TRight>>
{
internal Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<TRight>, TypedSqlPredicate> OnSqlPredicate { get; private set; }
internal string OnRawCondition { get; private set; }
public TypedScopeJoinBuilder<T1, T2, T3, T4, TRight> OnSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<TRight>, TypedSqlPredicate> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
OnSqlPredicate = predicate;
OnRawCondition = null;
return this;
}
public TypedScopeJoinBuilder<T1, T2, T3, T4, TRight> OnRaw(string condition)
{
if (string.IsNullOrEmpty(condition))
throw new ArgumentNullException("condition");
OnRawCondition = condition.Trim();
OnSqlPredicate = null;
return this;
}
}
namespace Extensions
{
internal static class DynamicHavingQueryExtensions
@@ -11589,6 +11831,10 @@ namespace DynamORM
TypedSqlRenderContext context = new TypedSqlRenderContext(this);
return predicate.Render(context);
}
internal string RenderScopeSqlPredicate(TypedSqlPredicate predicate)
{
return RenderSqlPredicate(predicate);
}
private string ParseTypedCondition(Expression expression)
{
expression = UnwrapConvert(expression);
@@ -11981,6 +12227,475 @@ namespace DynamORM
return getter();
}
}
internal abstract class DynamicTypedSelectScopeQueryBuilderBase<TRoot> : IDynamicSelectQueryBuilder
{
protected readonly DynamicTypedSelectQueryBuilder<TRoot> Builder;
protected DynamicTypedSelectScopeQueryBuilderBase(DynamicTypedSelectQueryBuilder<TRoot> builder)
{
Builder = builder;
}
public DynamicDatabase Database { get { return Builder.Database; } }
public IList<ITableInfo> Tables { get { return Builder.Tables; } }
public IDictionary<string, IParameter> Parameters { get { return Builder.Parameters; } }
public bool VirtualMode { get { return Builder.VirtualMode; } set { Builder.VirtualMode = value; } }
public bool SupportSchema { get { return Builder.SupportSchema; } }
public List<Action<IParameter>> OnCreateTemporaryParameter { get { return Builder.OnCreateTemporaryParameter; } set { Builder.OnCreateTemporaryParameter = value; } }
public List<Action<IParameter, IDbDataParameter>> OnCreateParameter { get { return Builder.OnCreateParameter; } set { Builder.OnCreateParameter = value; } }
public bool IsDisposed { get { return Builder.IsDisposed; } }
public void Dispose()
{
Builder.Dispose();
}
public IDbCommand FillCommand(IDbCommand command)
{
return Builder.FillCommand(command);
}
public string CommandText()
{
return Builder.CommandText();
}
public IEnumerable<dynamic> Execute()
{
return Builder.Execute();
}
public IEnumerable<T> Execute<T>() where T : class
{
return Builder.Execute<T>();
}
public void ExecuteDataReader(Action<IDataReader> reader)
{
Builder.ExecuteDataReader(reader);
}
public object Scalar()
{
return Builder.Scalar();
}
#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
public TResult ScalarAs<TResult>(TResult defaultValue = default(TResult))
{
return Builder.ScalarAs(defaultValue);
}
#endif
public IDynamicSelectQueryBuilder From(Func<dynamic, object> fn, params Func<dynamic, object>[] func)
{
Builder.From(fn, func);
return this;
}
public IDynamicSelectQueryBuilder Join(params Func<dynamic, object>[] func)
{
Builder.Join(func);
return this;
}
public IDynamicSelectQueryBuilder Where(Func<dynamic, object> func)
{
Builder.Where(func);
return this;
}
public IDynamicSelectQueryBuilder Where(DynamicColumn column)
{
Builder.Where(column);
return this;
}
public IDynamicSelectQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value)
{
Builder.Where(column, op, value);
return this;
}
public IDynamicSelectQueryBuilder Where(string column, object value)
{
Builder.Where(column, value);
return this;
}
public IDynamicSelectQueryBuilder Where(object conditions, bool schema = false)
{
Builder.Where(conditions, schema);
return this;
}
public IDynamicSelectQueryBuilder Select(Func<dynamic, object> fn, params Func<dynamic, object>[] func)
{
Builder.Select(fn, func);
return this;
}
public IDynamicSelectQueryBuilder SelectColumn(params DynamicColumn[] columns)
{
Builder.SelectColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder SelectColumn(params string[] columns)
{
Builder.SelectColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder GroupBy(Func<dynamic, object> fn, params Func<dynamic, object>[] func)
{
Builder.GroupBy(fn, func);
return this;
}
public IDynamicSelectQueryBuilder GroupByColumn(params DynamicColumn[] columns)
{
Builder.GroupByColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder GroupByColumn(params string[] columns)
{
Builder.GroupByColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder Having(Func<dynamic, object> func)
{
Builder.Having(func);
return this;
}
public IDynamicSelectQueryBuilder Having(DynamicColumn column)
{
Builder.Having(column);
return this;
}
public IDynamicSelectQueryBuilder Having(string column, DynamicColumn.CompareOperator op, object value)
{
Builder.Having(column, op, value);
return this;
}
public IDynamicSelectQueryBuilder Having(string column, object value)
{
Builder.Having(column, value);
return this;
}
public IDynamicSelectQueryBuilder Having(object conditions, bool schema = false)
{
Builder.Having(conditions, schema);
return this;
}
public IDynamicSelectQueryBuilder OrderBy(Func<dynamic, object> fn, params Func<dynamic, object>[] func)
{
Builder.OrderBy(fn, func);
return this;
}
public IDynamicSelectQueryBuilder OrderByColumn(params DynamicColumn[] columns)
{
Builder.OrderByColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder OrderByColumn(params string[] columns)
{
Builder.OrderByColumn(columns);
return this;
}
public IDynamicSelectQueryBuilder Top(int? top)
{
Builder.Top(top);
return this;
}
public IDynamicSelectQueryBuilder Limit(int? limit)
{
Builder.Limit(limit);
return this;
}
public IDynamicSelectQueryBuilder Offset(int? offset)
{
Builder.Offset(offset);
return this;
}
public IDynamicSelectQueryBuilder Distinct(bool distinct = true)
{
Builder.Distinct(distinct);
return this;
}
protected string GetJoinKeyword(DynamicJoinType joinType)
{
switch (joinType)
{
case DynamicJoinType.Join:
return "JOIN";
case DynamicJoinType.Left:
return "LEFT JOIN";
case DynamicJoinType.Right:
return "RIGHT JOIN";
case DynamicJoinType.Full:
return "FULL JOIN";
case DynamicJoinType.LeftOuter:
return "LEFT OUTER JOIN";
case DynamicJoinType.RightOuter:
return "RIGHT OUTER JOIN";
case DynamicJoinType.FullOuter:
return "FULL OUTER JOIN";
default:
return "INNER JOIN";
}
}
protected TypedJoinBuilder<TRoot, TJoin> ApplyJoinSpec<TJoin>(TypedJoinBuilder<TRoot, TJoin> builder, string alias, string customJoinType, DynamicJoinType joinType, bool noLock, string condition)
{
if (!string.IsNullOrEmpty(alias))
builder.As(alias);
if (!string.IsNullOrEmpty(customJoinType))
builder.Type(customJoinType);
else
{
switch (joinType)
{
case DynamicJoinType.Join: builder.Join(); break;
case DynamicJoinType.Left: builder.Left(); break;
case DynamicJoinType.Right: builder.Right(); break;
case DynamicJoinType.Full: builder.Full(); break;
case DynamicJoinType.LeftOuter: builder.LeftOuter(); break;
case DynamicJoinType.RightOuter: builder.RightOuter(); break;
case DynamicJoinType.FullOuter: builder.FullOuter(); break;
default: builder.Inner(); break;
}
}
if (noLock)
builder.NoLock();
if (!string.IsNullOrEmpty(condition))
builder.OnRaw(condition);
return builder;
}
}
internal sealed class DynamicTypedSelectScopeQueryBuilder<T1> : DynamicTypedSelectScopeQueryBuilderBase<T1>, IDynamicTypedSelectScopeQueryBuilder<T1>
{
private readonly string _alias1;
internal DynamicTypedSelectScopeQueryBuilder(DynamicTypedSelectQueryBuilder<T1> builder, string alias1)
: base(builder)
{
_alias1 = alias1;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, TJoin1> Join<TJoin1>(Func<TypedScopeJoinBuilder<T1, TJoin1>, TypedScopeJoinBuilder<T1, TJoin1>> specification)
{
if (specification == null)
throw new ArgumentNullException("specification");
TypedScopeJoinBuilder<T1, TJoin1> spec = specification(new TypedScopeJoinBuilder<T1, TJoin1>());
if (spec == null)
throw new ArgumentException("Join specification cannot resolve to null.", "specification");
string alias = string.IsNullOrEmpty(spec.Alias) ? "t2" : spec.Alias;
string condition = spec.OnSqlPredicate == null ? spec.OnRawCondition : Builder.RenderScopeSqlPredicate(spec.OnSqlPredicate(new TypedTableContext<T1>(_alias1), new TypedTableContext<TJoin1>(alias)));
Builder.Join<TJoin1>(j => ApplyJoinSpec(j, alias, spec.CustomJoinType, spec.JoinType, spec.UseNoLock, condition));
return new DynamicTypedSelectScopeQueryBuilder<T1, TJoin1>(Builder, _alias1, alias);
}
public IDynamicTypedSelectScopeQueryBuilder<T1> SelectSql(Func<TypedTableContext<T1>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedSqlSelectable>[] selectors)
{
Builder.SelectSql(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1> WhereSql(Func<TypedTableContext<T1>, TypedSqlPredicate> predicate)
{
Builder.WhereSql(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1> HavingSql(Func<TypedTableContext<T1>, TypedSqlPredicate> predicate)
{
Builder.HavingSql(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1> GroupBySql(Func<TypedTableContext<T1>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedSqlExpression>[] selectors)
{
Builder.GroupBySql(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1> OrderBySql(Func<TypedTableContext<T1>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedSqlOrderExpression>[] selectors)
{
Builder.OrderBySql(selector, selectors);
return this;
}
}
internal sealed class DynamicTypedSelectScopeQueryBuilder<T1, T2> : DynamicTypedSelectScopeQueryBuilderBase<T1>, IDynamicTypedSelectScopeQueryBuilder<T1, T2>
{
private readonly string _alias1;
private readonly string _alias2;
internal DynamicTypedSelectScopeQueryBuilder(DynamicTypedSelectQueryBuilder<T1> builder, string alias1, string alias2)
: base(builder)
{
_alias1 = alias1;
_alias2 = alias2;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, TJoin3> Join<TJoin3>(Func<TypedScopeJoinBuilder<T1, T2, TJoin3>, TypedScopeJoinBuilder<T1, T2, TJoin3>> specification)
{
if (specification == null)
throw new ArgumentNullException("specification");
TypedScopeJoinBuilder<T1, T2, TJoin3> spec = specification(new TypedScopeJoinBuilder<T1, T2, TJoin3>());
if (spec == null)
throw new ArgumentException("Join specification cannot resolve to null.", "specification");
string alias = string.IsNullOrEmpty(spec.Alias) ? "t3" : spec.Alias;
string condition = spec.OnSqlPredicate == null ? spec.OnRawCondition : Builder.RenderScopeSqlPredicate(spec.OnSqlPredicate(new TypedTableContext<T1>(_alias1), new TypedTableContext<T2>(_alias2), new TypedTableContext<TJoin3>(alias)));
Builder.Join<TJoin3>(j => ApplyJoinSpec(j, alias, spec.CustomJoinType, spec.JoinType, spec.UseNoLock, condition));
return new DynamicTypedSelectScopeQueryBuilder<T1, T2, TJoin3>(Builder, _alias1, _alias2, alias);
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlSelectable>[] selectors)
{
Builder.SelectSql<T2>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlPredicate> predicate)
{
Builder.WhereSql<T2>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlPredicate> predicate)
{
Builder.HavingSql<T2>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlExpression>[] selectors)
{
Builder.GroupBySql<T2>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedSqlOrderExpression>[] selectors)
{
Builder.OrderBySql<T2>(selector, selectors);
return this;
}
}
internal sealed class DynamicTypedSelectScopeQueryBuilder<T1, T2, T3> : DynamicTypedSelectScopeQueryBuilderBase<T1>, IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3>
{
private readonly string _alias1;
private readonly string _alias2;
private readonly string _alias3;
internal DynamicTypedSelectScopeQueryBuilder(DynamicTypedSelectQueryBuilder<T1> builder, string alias1, string alias2, string alias3)
: base(builder)
{
_alias1 = alias1;
_alias2 = alias2;
_alias3 = alias3;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, TJoin4> Join<TJoin4>(Func<TypedScopeJoinBuilder<T1, T2, T3, TJoin4>, TypedScopeJoinBuilder<T1, T2, T3, TJoin4>> specification)
{
if (specification == null)
throw new ArgumentNullException("specification");
TypedScopeJoinBuilder<T1, T2, T3, TJoin4> spec = specification(new TypedScopeJoinBuilder<T1, T2, T3, TJoin4>());
if (spec == null)
throw new ArgumentException("Join specification cannot resolve to null.", "specification");
string alias = string.IsNullOrEmpty(spec.Alias) ? "t4" : spec.Alias;
string condition = spec.OnSqlPredicate == null ? spec.OnRawCondition : Builder.RenderScopeSqlPredicate(spec.OnSqlPredicate(new TypedTableContext<T1>(_alias1), new TypedTableContext<T2>(_alias2), new TypedTableContext<T3>(_alias3), new TypedTableContext<TJoin4>(alias)));
Builder.Join<TJoin4>(j => ApplyJoinSpec(j, alias, spec.CustomJoinType, spec.JoinType, spec.UseNoLock, condition));
return new DynamicTypedSelectScopeQueryBuilder<T1, T2, T3, TJoin4>(Builder, _alias1, _alias2, _alias3, alias);
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlSelectable>[] selectors)
{
Builder.SelectSql<T2, T3>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlPredicate> predicate)
{
Builder.WhereSql<T2, T3>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlPredicate> predicate)
{
Builder.HavingSql<T2, T3>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlExpression>[] selectors)
{
Builder.GroupBySql<T2, T3>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedSqlOrderExpression>[] selectors)
{
Builder.OrderBySql<T2, T3>(selector, selectors);
return this;
}
}
internal sealed class DynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> : DynamicTypedSelectScopeQueryBuilderBase<T1>, IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4>
{
private readonly string _alias1;
private readonly string _alias2;
private readonly string _alias3;
private readonly string _alias4;
internal DynamicTypedSelectScopeQueryBuilder(DynamicTypedSelectQueryBuilder<T1> builder, string alias1, string alias2, string alias3, string alias4)
: base(builder)
{
_alias1 = alias1;
_alias2 = alias2;
_alias3 = alias3;
_alias4 = alias4;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, TJoin5> Join<TJoin5>(Func<TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5>, TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5>> specification)
{
if (specification == null)
throw new ArgumentNullException("specification");
TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5> spec = specification(new TypedScopeJoinBuilder<T1, T2, T3, T4, TJoin5>());
if (spec == null)
throw new ArgumentException("Join specification cannot resolve to null.", "specification");
string alias = string.IsNullOrEmpty(spec.Alias) ? "t5" : spec.Alias;
string condition = spec.OnSqlPredicate == null ? spec.OnRawCondition : Builder.RenderScopeSqlPredicate(spec.OnSqlPredicate(new TypedTableContext<T1>(_alias1), new TypedTableContext<T2>(_alias2), new TypedTableContext<T3>(_alias3), new TypedTableContext<T4>(_alias4), new TypedTableContext<TJoin5>(alias)));
Builder.Join<TJoin5>(j => ApplyJoinSpec(j, alias, spec.CustomJoinType, spec.JoinType, spec.UseNoLock, condition));
return new DynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, TJoin5>(Builder, _alias1, _alias2, _alias3, _alias4, alias);
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlSelectable>[] selectors)
{
Builder.SelectSql<T2, T3, T4>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlPredicate> predicate)
{
Builder.WhereSql<T2, T3, T4>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlPredicate> predicate)
{
Builder.HavingSql<T2, T3, T4>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlExpression>[] selectors)
{
Builder.GroupBySql<T2, T3, T4>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedSqlOrderExpression>[] selectors)
{
Builder.OrderBySql<T2, T3, T4>(selector, selectors);
return this;
}
}
internal sealed class DynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> : DynamicTypedSelectScopeQueryBuilderBase<T1>, IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5>
{
internal DynamicTypedSelectScopeQueryBuilder(DynamicTypedSelectQueryBuilder<T1> builder, string alias1, string alias2, string alias3, string alias4, string alias5)
: base(builder)
{
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> SelectSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlSelectable> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlSelectable>[] selectors)
{
Builder.SelectSql<T2, T3, T4, T5>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> WhereSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlPredicate> predicate)
{
Builder.WhereSql<T2, T3, T4, T5>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> HavingSql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlPredicate> predicate)
{
Builder.HavingSql<T2, T3, T4, T5>(predicate);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> GroupBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlExpression>[] selectors)
{
Builder.GroupBySql<T2, T3, T4, T5>(selector, selectors);
return this;
}
public IDynamicTypedSelectScopeQueryBuilder<T1, T2, T3, T4, T5> OrderBySql(Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlOrderExpression> selector, params Func<TypedTableContext<T1>, TypedTableContext<T2>, TypedTableContext<T3>, TypedTableContext<T4>, TypedTableContext<T5>, TypedSqlOrderExpression>[] selectors)
{
Builder.OrderBySql<T2, T3, T4, T5>(selector, selectors);
return this;
}
}
/// <summary>Typed wrapper over <see cref="DynamicUpdateQueryBuilder"/> with property-to-column translation.</summary>
/// <typeparam name="T">Mapped entity type.</typeparam>
internal class DynamicTypedUpdateQueryBuilder<T> : DynamicUpdateQueryBuilder, IDynamicTypedUpdateQueryBuilder<T>