|
@@ -61,6 +61,518 @@ namespace InABox.Core
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ #region ComplexFormula
|
|
|
+
|
|
|
+ public static class ComplexFormula
|
|
|
+ {
|
|
|
+ public static IComplexFormulaFieldNode Field(Type T, Type TResult, string field)
|
|
|
+ {
|
|
|
+ var type = typeof(ComplexFormulaFieldNode<,>).MakeGenericType(T, TResult);
|
|
|
+ return (Activator.CreateInstance(type, field) as IComplexFormulaFieldNode)!;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IComplexFormulaNode
|
|
|
+ {
|
|
|
+ Type TType { get; }
|
|
|
+
|
|
|
+ IComplexColumn ToColumn(string columnName);
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IComplexFormulaNode<TType, TResult> : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ Type IComplexFormulaNode.TType => typeof(TType);
|
|
|
+
|
|
|
+ IComplexColumn IComplexFormulaNode.ToColumn(string columnName) => new ComplexColumn<TType, TResult>(columnName, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ #region FieldNode
|
|
|
+
|
|
|
+ public interface IComplexFormulaFieldNode : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ string GetField();
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ComplexFormulaFieldNode<TType, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaFieldNode
|
|
|
+ {
|
|
|
+ //public Expression<Func<TType, TResult>> Expression { get; set; }
|
|
|
+ public string Field { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaFieldNode(Expression<Func<TType, TResult>> expression)
|
|
|
+ {
|
|
|
+ Field = CoreUtils.GetFullPropertyName(expression, ".");
|
|
|
+ }
|
|
|
+
|
|
|
+ internal ComplexFormulaFieldNode(string field)
|
|
|
+ {
|
|
|
+ Field = field;
|
|
|
+ }
|
|
|
+
|
|
|
+ string IComplexFormulaFieldNode.GetField() => Field;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region ConstantNode
|
|
|
+
|
|
|
+ public interface IComplexFormulaConstantNode : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ object? GetConstant();
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ComplexFormulaConstantNode<TType, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaConstantNode
|
|
|
+ {
|
|
|
+ public TResult Constant { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaConstantNode(TResult constant)
|
|
|
+ {
|
|
|
+ Constant = constant;
|
|
|
+ }
|
|
|
+
|
|
|
+ object? IComplexFormulaConstantNode.GetConstant() => Constant;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region AggregateNode
|
|
|
+
|
|
|
+ public interface IComplexFormulaAggregateNode : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ Type TAggregate { get; }
|
|
|
+
|
|
|
+ IComplexFormulaNode GetExpression();
|
|
|
+
|
|
|
+ AggregateCalculation GetCalculation();
|
|
|
+
|
|
|
+ IFilter? GetFilter();
|
|
|
+
|
|
|
+ Dictionary<string, string> GetLinks();
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ComplexFormulaAggregateNode<TType, TAggregate, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaAggregateNode
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TAggregate, TResult> Expression { get; set; }
|
|
|
+
|
|
|
+ public AggregateCalculation Calculation { get; set; }
|
|
|
+
|
|
|
+ public Filter<TAggregate>? Filter { get; set; }
|
|
|
+
|
|
|
+ public Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> Links { get; }
|
|
|
+
|
|
|
+ Type IComplexFormulaAggregateNode.TAggregate => typeof(TAggregate);
|
|
|
+
|
|
|
+ public ComplexFormulaAggregateNode(IComplexFormulaNode<TAggregate, TResult> expression, AggregateCalculation calculation, Filter<TAggregate>? filter, Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> links)
|
|
|
+ {
|
|
|
+ Expression = expression;
|
|
|
+ Calculation = calculation;
|
|
|
+ Filter = filter;
|
|
|
+ Links = links;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, 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)
|
|
|
+ {
|
|
|
+ Links.Add(aggLink, masterLink);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ #region IComplexFormulaAggregateNode
|
|
|
+
|
|
|
+ IComplexFormulaNode IComplexFormulaAggregateNode.GetExpression()
|
|
|
+ {
|
|
|
+ return Expression;
|
|
|
+ }
|
|
|
+
|
|
|
+ AggregateCalculation IComplexFormulaAggregateNode.GetCalculation()
|
|
|
+ {
|
|
|
+ return Calculation;
|
|
|
+ }
|
|
|
+
|
|
|
+ IFilter? IComplexFormulaAggregateNode.GetFilter()
|
|
|
+ {
|
|
|
+ return Filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ Dictionary<string, string> IComplexFormulaAggregateNode.GetLinks()
|
|
|
+ {
|
|
|
+ return Links.ToDictionary(x => CoreUtils.GetFullPropertyName(x.Key, "."), x => CoreUtils.GetFullPropertyName(x.Value, "."));
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Represents an aggregate that has no links set; call <see cref="WithLink(Expression{Func{TAggregate, object?}}, Expression{Func{TType, object?}})"/> to
|
|
|
+ /// set the link.
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="TType"></typeparam>
|
|
|
+ /// <typeparam name="TAggregate"></typeparam>
|
|
|
+ /// <typeparam name="TResult"></typeparam>
|
|
|
+ public class ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult>
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TAggregate, TResult> 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)
|
|
|
+ {
|
|
|
+ Expression = expression;
|
|
|
+ Calculation = calculation;
|
|
|
+ Filter = filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, 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)
|
|
|
+ {
|
|
|
+ var node = new ComplexFormulaAggregateNode<TType, TAggregate, 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(
|
|
|
+ Dictionary<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>> links)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(Expression, Calculation, Filter, links);
|
|
|
+ }
|
|
|
+ public ComplexFormulaAggregateNode<TType, TAggregate, 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?>>>());
|
|
|
+ node.Links.AddRange(links);
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region FormulaNode
|
|
|
+
|
|
|
+ public interface IComplexFormulaFormulaNode : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ IEnumerable<IComplexFormulaNode> GetOperands();
|
|
|
+
|
|
|
+ FormulaOperator GetOperator();
|
|
|
+ }
|
|
|
+ public class ComplexFormulaFormulaNode<TType, TResult> : IComplexFormulaNode<TType, TResult>, IComplexFormulaFormulaNode
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TType, TResult>[] Operands { get; set; }
|
|
|
+
|
|
|
+ public FormulaOperator Operator { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaFormulaNode(IComplexFormulaNode<TType, TResult>[] operands, FormulaOperator op)
|
|
|
+ {
|
|
|
+ Operands = operands;
|
|
|
+ Operator = op;
|
|
|
+ }
|
|
|
+
|
|
|
+ IEnumerable<IComplexFormulaNode> IComplexFormulaFormulaNode.GetOperands() => Operands;
|
|
|
+
|
|
|
+ FormulaOperator IComplexFormulaFormulaNode.GetOperator() => Operator;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region ConditionNode
|
|
|
+
|
|
|
+ public class ComplexFormulaPartial0ConditionNode<TType, TCondition, TValue>
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Left { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Right { get; set; }
|
|
|
+
|
|
|
+ public Condition Condition { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaPartial0ConditionNode(IComplexFormulaNode<TType, TCondition> left, IComplexFormulaNode<TType, TCondition> right, Condition condition)
|
|
|
+ {
|
|
|
+ Left = left;
|
|
|
+ Right = right;
|
|
|
+ Condition = condition;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartial1ConditionNode<TType, TCondition, TValue> Then(IComplexFormulaNode<TType, TValue> then)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaPartial1ConditionNode<TType, TCondition, TValue>(Left, Right, Condition, then);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ComplexFormulaPartial1ConditionNode<TType, TCondition, TValue>
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Left { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Right { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TValue> True { get; set; }
|
|
|
+
|
|
|
+ public Condition Condition { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaPartial1ConditionNode(IComplexFormulaNode<TType, TCondition> left, IComplexFormulaNode<TType, TCondition> right, Condition condition, IComplexFormulaNode<TType, TValue> trueValue)
|
|
|
+ {
|
|
|
+ Left = left;
|
|
|
+ Right = right;
|
|
|
+ Condition = condition;
|
|
|
+ True = trueValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaConditionNode<TType, TCondition, TValue> Else(IComplexFormulaNode<TType, TValue> elseValue)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaConditionNode<TType, TCondition, TValue>(Left, Right, True, elseValue, Condition);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IComplexFormulaConditionNode : IComplexFormulaNode
|
|
|
+ {
|
|
|
+ public Type TCondition { get; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode Left { get; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode Right { get; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode True { get; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode False { get; }
|
|
|
+
|
|
|
+ public Condition Condition { get; }
|
|
|
+ }
|
|
|
+ public class ComplexFormulaConditionNode<TType, TCondition, TValue> : IComplexFormulaNode<TType, TValue>, IComplexFormulaConditionNode
|
|
|
+ {
|
|
|
+ Type IComplexFormulaConditionNode.TCondition => typeof(TCondition);
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Left { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TCondition> Right { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TValue> True { get; set; }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TValue> False { get; set; }
|
|
|
+
|
|
|
+ public Condition Condition { get; set; }
|
|
|
+
|
|
|
+ public ComplexFormulaConditionNode(IComplexFormulaNode<TType, TCondition> left, IComplexFormulaNode<TType, TCondition> right, IComplexFormulaNode<TType, TValue> trueValue, IComplexFormulaNode<TType, TValue> falseValue, Condition condition)
|
|
|
+ {
|
|
|
+ Left = left;
|
|
|
+ Right = right;
|
|
|
+ True = trueValue;
|
|
|
+ False = falseValue;
|
|
|
+ Condition = condition;
|
|
|
+ }
|
|
|
+
|
|
|
+ IComplexFormulaNode IComplexFormulaConditionNode.Left => Left;
|
|
|
+ IComplexFormulaNode IComplexFormulaConditionNode.Right => Right;
|
|
|
+ IComplexFormulaNode IComplexFormulaConditionNode.True => True;
|
|
|
+ IComplexFormulaNode IComplexFormulaConditionNode.False => False;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region Generator + Interface
|
|
|
+
|
|
|
+ public interface IComplexFormulaGenerator
|
|
|
+ {
|
|
|
+ IComplexFormulaNode GetFormula();
|
|
|
+ }
|
|
|
+
|
|
|
+ public abstract class ComplexFormulaGenerator
|
|
|
+ {
|
|
|
+ public static IComplexFormulaNode<TType, TResult> Property<TType, TResult>(Expression<Func<TType, TResult>> expression)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaFieldNode<TType, TResult>(expression);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IComplexFormulaNode<TType, TResult> Formula<TType, TResult>(FormulaOperator op, params IComplexFormulaNode<TType, TResult>[] operands)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaFormulaNode<TType, TResult>(operands, op);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IComplexFormulaNode<TType, TResult> Aggregate<TType, TAggregate, TResult>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ IComplexFormulaNode<TAggregate, TResult> expression,
|
|
|
+ KeyValuePair<Expression<Func<TAggregate, object?>>, Expression<Func<TType, object?>>>[] links,
|
|
|
+ Filter<TAggregate>? filter = null
|
|
|
+ )
|
|
|
+ {
|
|
|
+ return new ComplexFormulaAggregateNode<TType, TAggregate, TResult>(expression, calculation, filter, links.ToDictionary(x => x.Key, x => x.Value));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TType, TAggregate, TResult>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ IComplexFormulaNode<TAggregate, TResult> expression,
|
|
|
+ Filter<TAggregate>? filter = null
|
|
|
+ )
|
|
|
+ {
|
|
|
+ return new ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult>(expression, calculation, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static IComplexFormulaNode<TType, TResult> Constant<TType, TResult>(TResult constant)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaConstantNode<TType, TResult>(constant);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ComplexFormulaPartial0ConditionNode<TType, TCondition, TValue> If<TType, TCondition, TValue>(
|
|
|
+ IComplexFormulaNode<TType, TCondition> left,
|
|
|
+ Condition condition,
|
|
|
+ IComplexFormulaNode<TType, TCondition> right)
|
|
|
+ {
|
|
|
+ return new ComplexFormulaPartial0ConditionNode<TType, TCondition, TValue>(left, right, condition);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IComplexFormulaGenerator<TType, TResult>
|
|
|
+ {
|
|
|
+ IComplexFormulaNode<TType, TResult> Property(Expression<Func<TType, TResult>> epxression);
|
|
|
+
|
|
|
+ IComplexFormulaNode<TType, TResult> Formula(FormulaOperator op, params IComplexFormulaNode<TType, TResult>[] operands);
|
|
|
+
|
|
|
+ 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>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
+ Filter<TAggregate>? filter = null
|
|
|
+ );
|
|
|
+
|
|
|
+ ComplexFormulaPartial0ConditionNode<TType, TCondition, TResult> If<TCondition>(
|
|
|
+ Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> left,
|
|
|
+ Condition condition,
|
|
|
+ Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> right);
|
|
|
+ }
|
|
|
+
|
|
|
+ internal class InternalComplexFormulaGenerator<TType, TResult> : IComplexFormulaGenerator<TType, TResult>
|
|
|
+ {
|
|
|
+ public IComplexFormulaNode<TType, TResult> Property(Expression<Func<TType, TResult>> expression)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Property(expression);
|
|
|
+ }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TResult> Formula(FormulaOperator op, params IComplexFormulaNode<TType, TResult>[] operands)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Formula(op, operands);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 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>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
+ Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ComplexFormulaGenerator.Aggregate<TType, TAggregate, TResult>(calculation, expression(new InternalComplexFormulaGenerator<TAggregate, TResult>()), filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartial0ConditionNode<TType, TCondition, TResult> If<TCondition>(
|
|
|
+ Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> left,
|
|
|
+ Condition condition,
|
|
|
+ Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> right)
|
|
|
+ {
|
|
|
+ var generator = new InternalComplexFormulaGenerator<TType, TCondition>();
|
|
|
+ return ComplexFormulaGenerator.If<TType, TCondition, TResult>(
|
|
|
+ left(generator),
|
|
|
+ condition,
|
|
|
+ right(generator));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public abstract class ComplexFormulaGenerator<TType, TResult> : ComplexFormulaGenerator, IComplexFormulaGenerator<TType, TResult>, IComplexFormulaGenerator
|
|
|
+ {
|
|
|
+ public abstract IComplexFormulaNode<TType, TResult> GetFormula();
|
|
|
+
|
|
|
+ #region Internals
|
|
|
+
|
|
|
+ IComplexFormulaNode IComplexFormulaGenerator.GetFormula() => GetFormula();
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TResult> Property(Expression<Func<TType, TResult>> epxression)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Property(epxression);
|
|
|
+ }
|
|
|
+
|
|
|
+ public IComplexFormulaNode<TType, TResult> Constant(TResult constant)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Constant(constant);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartialAggregateNode<TType, TAggregate, TResult> Aggregate<TAggregate>(
|
|
|
+ AggregateCalculation calculation,
|
|
|
+ Func<IComplexFormulaGenerator<TAggregate, TResult>, IComplexFormulaNode<TAggregate, TResult>> expression,
|
|
|
+ Filter<TAggregate>? filter = null)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).Aggregate(calculation, expression, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ComplexFormulaPartial0ConditionNode<TType, TCondition, TResult> If<TCondition>(Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> left, Condition condition, Func<IComplexFormulaGenerator<TType, TCondition>, IComplexFormulaNode<TType, TCondition>> right)
|
|
|
+ {
|
|
|
+ return ((IComplexFormulaGenerator<TType, TResult>)InternalGenerator).If(left, condition, right);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ComplexFormulaAttribute : Attribute
|
|
|
+ {
|
|
|
+ public IComplexFormulaGenerator Generator { get; }
|
|
|
+
|
|
|
+ public ComplexFormulaAttribute(Type generator)
|
|
|
+ {
|
|
|
+ var obj = Activator.CreateInstance(generator);
|
|
|
+ if(obj is IComplexFormulaGenerator g)
|
|
|
+ {
|
|
|
+ Generator = g;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new Exception($"{nameof(ComplexFormulaAttribute)}: {generator} is not a {typeof(IComplexFormulaGenerator)}!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
#region Aggregates
|
|
|
|
|
|
public enum AggregateCalculation
|