|
@@ -151,9 +151,19 @@ namespace InABox.Core
|
|
|
Dictionary<string, string> GetLinks();
|
|
|
}
|
|
|
|
|
|
- public class ComplexFormulaAggregateNode<TType, TAggregate, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaAggregateNode
|
|
|
+ /// <summary>
|
|
|
+ /// Represents an aggregate, to form a single value from another table in the database.
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="TType">The type of the parent table, on which this formula is defined.</typeparam>
|
|
|
+ /// <typeparam name="TAggregate">The type of the child table, which is being aggregated.</typeparam>
|
|
|
+ /// <typeparam name="TExpression">The type of the property which is being aggregated.</typeparam>
|
|
|
+ /// <typeparam name="TResult">
|
|
|
+ /// The type of the result of the aggregate. In most cases, this will be the same as <typeparamref name="TExpression"/>,
|
|
|
+ /// except for aggregates like <see cref="AggregateCalculation.Count"/>, which will always be <see cref="int"/>.
|
|
|
+ /// </typeparam>
|
|
|
+ public class ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaAggregateNode
|
|
|
{
|
|
|
- public IComplexFormulaNode<TAggregate, TResult> Expression { get; set; }
|
|
|
+ public IComplexFormulaNode<TAggregate, TExpression> Expression { get; set; }
|
|
|
|
|
|
public AggregateCalculation Calculation { get; set; }
|
|
|
|
|
@@ -165,7 +175,7 @@ namespace InABox.Core
|
|
|
|
|
|
Type IComplexFormulaAggregateNode.TResult => typeof(TResult);
|
|
|
|
|
|
- public ComplexFormulaAggregateNode(IComplexFormulaNode<TAggregate, TResult> expression, AggregateCalculation calculation, Filter<TAggregate>? filter, Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> links)
|
|
|
+ public ComplexFormulaAggregateNode(IComplexFormulaNode<TAggregate, TExpression> expression, AggregateCalculation calculation, Filter<TAggregate>? filter, Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> links)
|
|
|
{
|
|
|
Expression = expression;
|
|
|
Calculation = calculation;
|
|
@@ -173,18 +183,18 @@ namespace InABox.Core
|
|
|
Links = links;
|
|
|
}
|
|
|
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithFilter(Filter<TAggregate> filter)
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithFilter(Filter<TAggregate> filter)
|
|
|
{
|
|
|
Filter = filter;
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLink(Expression<Func<TAggregate, object?>> aggLink, Expression<Func<TType, object?>> masterLink)
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLink(Expression<Func<TAggregate, object?>> aggLink, Expression<Func<TType, object?>> masterLink)
|
|
|
{
|
|
|
Links.Add(aggLink, masterLink);
|
|
|
return this;
|
|
|
}
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLinks(
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLinks(
|
|
|
IEnumerable<KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>> links)
|
|
|
{
|
|
|
Links.AddRange(links);
|
|
@@ -223,48 +233,48 @@ namespace InABox.Core
|
|
|
/// <typeparam name="TType"></typeparam>
|
|
|
/// <typeparam name="TAggregate"></typeparam>
|
|
|
/// <typeparam name="TResult"></typeparam>
|
|
|
- public class ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult>
|
|
|
+ public class ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, TResult>
|
|
|
{
|
|
|
- public IComplexFormulaNode<TAggregate, TResult> Expression { get; set; }
|
|
|
+ public IComplexFormulaNode<TAggregate, TExpression> Expression { get; set; }
|
|
|
|
|
|
public AggregateCalculation Calculation { get; set; }
|
|
|
|
|
|
public Filter<TAggregate>? Filter { get; set; }
|
|
|
|
|
|
- public ComplexFormulaPartialAggregateNode(IComplexFormulaNode<TAggregate, TResult> expression, AggregateCalculation calculation, Filter<TAggregate>? filter)
|
|
|
+ public ComplexFormulaPartialAggregateNode(IComplexFormulaNode<TAggregate, TExpression> expression, AggregateCalculation calculation, Filter<TAggregate>? filter)
|
|
|
{
|
|
|
Expression = expression;
|
|
|
Calculation = calculation;
|
|
|
Filter = filter;
|
|
|
}
|
|
|
|
|
|
- public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> WithFilter(Filter<TAggregate> filter)
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, TResult> WithFilter(Filter<TAggregate> filter)
|
|
|
{
|
|
|
Filter = filter;
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLink(Expression<Func<TAggregate, object?>> aggLink, Expression<Func<TType, object?>> masterLink)
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLink(Expression<Func<TAggregate, object?>> aggLink, Expression<Func<TType, object?>> masterLink)
|
|
|
{
|
|
|
- var node = new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(Expression, Calculation, Filter, new Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>());
|
|
|
+ var node = new ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult>(Expression, Calculation, Filter, new Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>());
|
|
|
node.Links.Add(aggLink, masterLink);
|
|
|
return node;
|
|
|
}
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLinks(
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLinks(
|
|
|
IEnumerable<KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>> links)
|
|
|
{
|
|
|
- return new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(Expression, Calculation, Filter,
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult>(Expression, Calculation, Filter,
|
|
|
new Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>().AddRange(links));
|
|
|
}
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLinks(
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLinks(
|
|
|
Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> links)
|
|
|
{
|
|
|
- return new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(Expression, Calculation, Filter, links);
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult>(Expression, Calculation, Filter, links);
|
|
|
}
|
|
|
- public ComplexFormulaAggregateNode<TType, TAggregate, TResult> WithLinks(
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult> WithLinks(
|
|
|
params KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links)
|
|
|
{
|
|
|
- var node = new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(Expression, Calculation, Filter, new Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>());
|
|
|
+ var node = new ComplexFormulaAggregateNode<TType, TAggregate, TExpression, TResult>(Expression, Calculation, Filter, new Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>());
|
|
|
node.Links.AddRange(links);
|
|
|
return node;
|
|
|
}
|
|
@@ -422,16 +432,32 @@ namespace InABox.Core
|
|
|
Filter<TAggregate>? filter = null
|
|
|
)
|
|
|
{
|
|
|
- return new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(expression, calculation, filter, links.ToDictionary(x => x.Key, x => x.Value));
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TResult, TResult>(expression, calculation, filter, links.ToDictionary(x => x.Key, x => x.Value));
|
|
|
}
|
|
|
|
|
|
- public static ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TType, TAggregate, TResult>(
|
|
|
+ public static ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult, TResult> Aggregate<TType, TAggregate, TResult>(
|
|
|
AggregateCalculation calculation,
|
|
|
IComplexFormulaNode<TAggregate, TResult> expression,
|
|
|
Filter<TAggregate>? filter = null
|
|
|
)
|
|
|
{
|
|
|
- return new ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult>(expression, calculation, filter);
|
|
|
+ return new ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult, TResult>(expression, calculation, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IComplexFormulaNode<TType, int> Count<TType, TAggregate, TExpression>(
|
|
|
+ IComplexFormulaNode<TAggregate, TExpression> expression,
|
|
|
+ KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
+ Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TExpression, int>(expression, AggregateCalculation.Count, filter, links.ToDictionary(x => x.Key, x => x.Value));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, int> Count<TType, TAggregate, TExpression>(
|
|
|
+ IComplexFormulaNode<TAggregate, TExpression> expression,
|
|
|
+ Filter<TAggregate>? filter = null
|
|
|
+ )
|
|
|
+ {
|
|
|
+ return new ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, int>(expression, AggregateCalculation.Count, filter);
|
|
|
}
|
|
|
|
|
|
public static IComplexFormulaNode<TType, TResult> Constant<TType, TResult>(TResult constant)
|
|
@@ -454,19 +480,27 @@ namespace InABox.Core
|
|
|
|
|
|
IComplexFormulaNode<TType, TResult> Formula(FormulaOperator op, params IComplexFormulaNode<TType, TResult>[] operands);
|
|
|
|
|
|
+ IComplexFormulaNode<TType, TResult> Constant(TResult constant);
|
|
|
+
|
|
|
IComplexFormulaNode<TType, TResult> Aggregate<TAggregate>(
|
|
|
AggregateCalculation calculation,
|
|
|
Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
Filter<TAggregate>? filter = null);
|
|
|
|
|
|
- IComplexFormulaNode<TType, TResult> Constant(TResult constant);
|
|
|
-
|
|
|
- ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TAggregate>(
|
|
|
+ ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult, TResult> Aggregate<TAggregate>(
|
|
|
AggregateCalculation calculation,
|
|
|
Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
- Filter<TAggregate>? filter = null
|
|
|
- );
|
|
|
+ Filter<TAggregate>? filter = null);
|
|
|
+
|
|
|
+ IComplexFormulaNode<TType, int> Count<TAggregate, TExpression>(
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression,
|
|
|
+ KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
+ Filter<TAggregate>? filter = null);
|
|
|
+
|
|
|
+ ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, int> Count<TAggregate, TExpression>(
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression,
|
|
|
+ Filter<TAggregate>? filter = null);
|
|
|
|
|
|
ComplexFormulaPartial0ConditionNode<TType, TCondition, TResult> If<TCondition>(
|
|
|
Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> left,
|
|
@@ -486,6 +520,11 @@ namespace InABox.Core
|
|
|
return ComplexFormulaGenerator.Formula(op, operands);
|
|
|
}
|
|
|
|
|
|
+ public IComplexFormulaNode<TType, TResult> Constant(TResult constant)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Constant<TType, TResult>(constant);
|
|
|
+ }
|
|
|
+
|
|
|
public IComplexFormulaNode<TType, TResult> Aggregate<TAggregate>(
|
|
|
AggregateCalculation calculation,
|
|
|
Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
@@ -495,12 +534,7 @@ namespace InABox.Core
|
|
|
return ComplexFormulaGenerator.Aggregate(calculation, expression(new InternalComplexFormulaGenerator<TAggregate, TResult>()), links, filter);
|
|
|
}
|
|
|
|
|
|
- public IComplexFormulaNode<TType, TResult> Constant(TResult constant)
|
|
|
- {
|
|
|
- return ComplexFormulaGenerator.Constant<TType, TResult>(constant);
|
|
|
- }
|
|
|
-
|
|
|
- public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TAggregate>(
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult, TResult> Aggregate<TAggregate>(
|
|
|
AggregateCalculation calculation,
|
|
|
Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
Filter<TAggregate>? filter = null)
|
|
@@ -519,6 +553,16 @@ namespace InABox.Core
|
|
|
condition,
|
|
|
right(generator));
|
|
|
}
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, int> Count<TAggregate, TExpression>(Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression, KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links, Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Count(expression(new InternalComplexFormulaGenerator<TAggregate, TExpression>()), links, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, int> Count<TAggregate, TExpression>(Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression, Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Count<TType, TAggregate, TExpression>(expression(new InternalComplexFormulaGenerator<TAggregate, TExpression>()), filter);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public abstract class ComplexFormulaGenerator<TType, TResult> : ComplexFormulaGenerator, IComplexFormulaGenerator<TType, TResult>, IComplexFormulaGenerator
|
|
@@ -531,15 +575,6 @@ namespace InABox.Core
|
|
|
|
|
|
private readonly InternalComplexFormulaGenerator<TType, TResult> InternalGenerator = new InternalComplexFormulaGenerator<TType, TResult>();
|
|
|
|
|
|
- public IComplexFormulaNode<TType, TResult> Aggregate<TAggregate>(
|
|
|
- AggregateCalculation calculation,
|
|
|
- Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
- KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
- Filter<TAggregate>? filter = null)
|
|
|
- {
|
|
|
- return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Aggregate(calculation, expression, links, filter);
|
|
|
- }
|
|
|
-
|
|
|
public IComplexFormulaNode<TType, TResult> Formula(FormulaOperator op, params IComplexFormulaNode<TType, TResult>[] operands)
|
|
|
{
|
|
|
return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Formula(op, operands);
|
|
@@ -555,7 +590,16 @@ namespace InABox.Core
|
|
|
return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Constant(constant);
|
|
|
}
|
|
|
|
|
|
- public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TAggregate>(
|
|
|
+ public IComplexFormulaNode<TType, TResult> Aggregate<TAggregate>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
+ KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
+ Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Aggregate(calculation, expression, links, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult, TResult> Aggregate<TAggregate>(
|
|
|
AggregateCalculation calculation,
|
|
|
Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
Filter<TAggregate>? filter = null)
|
|
@@ -568,6 +612,16 @@ namespace InABox.Core
|
|
|
return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).If(left, condition, right);
|
|
|
}
|
|
|
|
|
|
+ public IComplexFormulaNode<TType, int> Count<TAggregate, TExpression>(Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression, KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links, Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Count(expression, links, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TExpression, int> Count<TAggregate, TExpression>(Func<IComplexFormulaGenerator<TAggregate, TExpression>, IComplexFormulaNode<TAggregate, TExpression>> expression, Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Count(expression, filter);
|
|
|
+ }
|
|
|
+
|
|
|
#endregion
|
|
|
}
|
|
|
|