123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Runtime.CompilerServices;
- namespace InABox.Core
- {
- /*
- * Heres what we want to model - a view that performs in-table summaries. Currently we can define out-of-table lookups that sumamrise the values in another table,
- * but these all seem to generate multi-table queeries, which lose the performance benefits we're looking for. The below "target" query is a single-table query
- *
- select SUMMARYTABLE.* from
- (SELECT
- [location.id],
- [product.id],
- [style.id],
- [job.id],
- [dimensions.unit.id],
- [dimensions.Quantity],
- [dimensions.length],
- [dimensions.width],
- [dimensions.Height],
- [dimensions.weight],
- [dimensions.value],
- [dimensions.unitsize],
- sum(coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0)) AS Total,
- sum(case when [JOBREQUISITIONITEM.ID] is null THEN coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0) ELSE 0.0 end) AS Available,
- sum(case when [JOBREQUISITIONITEM.ID] is not null THEN coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0) ELSE 0.0 end) AS Allocated,
- sum((coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0)) * coalesce(COST,0.0)) AS TotalCost,
- sum((coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0)) * coalesce(COST,0.0)) / sum(coalesce([RECEIVED],0.0)-coalesce([ISSUED],0.0)) AS AverageCost
- FROM
- STOCKMOVEMENT
- GROUP BY
- [location.id],
- [product.id],
- [style.id],
- [job.id],
- [dimensions.unit.id],
- [dimensions.Quantity],
- [dimensions.length],
- [dimensions.width],
- [dimensions.Height],
- [dimensions.weight],
- [dimensions.value],
- [dimensions.unitsize]
- ) as SUMMARYTABLE
- WHERE
- SUMMARYTABLE.[PRODUCT.ID]='fc159c37-6a59-410b-b15c-8baed75349aa'
- */
- public enum AutoEntitySummaryAggregate
- {
- Sum,
- Average,
- Count,
- Minimum,
- Maximum
- }
-
- public interface IAutoEntitySummaryAggregateColumn : IColumn
- {
- AutoEntitySummaryAggregate Aggregate { get; }
- IComplexFormulaGenerator Definition { get; }
- }
-
- public class AutoEntitySummaryAggregateColumn<TInterface,TType> : Column<TInterface>, IAutoEntitySummaryAggregateColumn
- {
-
- public AutoEntitySummaryAggregate Aggregate { get; }
-
- public ComplexFormulaGenerator<TType,object?> Definition { get; }
- IComplexFormulaGenerator IAutoEntitySummaryAggregateColumn.Definition => Definition;
-
- public AutoEntitySummaryAggregateColumn(Expression<Func<TInterface, object?>> expression, AutoEntitySummaryAggregate aggregate, ComplexFormulaGenerator<TType,object?> definition) : base(expression)
- {
- Aggregate = aggregate;
- Definition = definition;
- }
-
- }
- public interface IAutoEntitySummaryIDColumn : IColumn
- {
- IColumn Source { get; }
- }
-
- public class AutoEntitySummaryIDColumn<TInterface,TType> : Column<TInterface>, IAutoEntitySummaryIDColumn
- {
-
- public Column<TType> Source { get; }
-
- IColumn IAutoEntitySummaryIDColumn.Source => Source;
-
- public AutoEntitySummaryIDColumn(Expression<Func<TInterface, object?>> expression, Expression<Func<TType, object?>> source) : base(expression)
- {
- Source = new Column<TType>(source);
- }
-
- }
- public interface IAutoEntitySummaryGenerator : IAutoEntityGenerator
- {
- new IAutoEntitySummaryIDColumn[] IDColumns();
- IAutoEntitySummaryAggregateColumn[] AggregateColumns();
- IFilter? HavingFilter { get; }
- Type SourceType { get; }
- }
-
- public abstract class AutoEntitySummaryGenerator<TInterface,TType> : IAutoEntitySummaryGenerator
- {
- public AutoEntitySummaryGenerator()
- {
- Configure();
- }
-
- public bool Distinct => false;
-
- public Type Definition => typeof(TInterface);
- public Type SourceType => typeof(TType);
- private List<IColumn> _idColumns = new List<IColumn>();
- private List<IAutoEntitySummaryAggregateColumn> _aggregateColumns = new List<IAutoEntitySummaryAggregateColumn>();
- private Filter<TInterface>? _filter = null;
-
- public abstract void Configure();
-
- protected void GroupBy(Expression<Func<TInterface,object?>> column, Expression<Func<TType,object?>> source)
- => _idColumns.Add(new AutoEntitySummaryIDColumn<TInterface,TType>(column,source));
-
- protected void Aggregate(Expression<Func<TInterface,object?>> column,AutoEntitySummaryAggregate aggregate, ComplexFormulaGenerator<TType,object?> formula)
- => _aggregateColumns.Add(new AutoEntitySummaryAggregateColumn<TInterface,TType>(column,aggregate, formula));
- protected void Having(Filter<TInterface> filter)
- => _filter = filter;
-
- public IAutoEntitySummaryIDColumn[] IDColumns() => _idColumns.OfType<IAutoEntitySummaryIDColumn>().ToArray();
- public IAutoEntitySummaryAggregateColumn[] AggregateColumns() => _aggregateColumns.ToArray();
- public IFilter? HavingFilter => _filter;
-
- IColumn[] IAutoEntityGenerator.IDColumns => _idColumns.ToArray();
-
- }
-
- }
|