using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace InABox.Core { public interface IAutoEntityUnionGenerator : IAutoEntityGenerator { IAutoEntityUnionTable[] Tables { get; } } public interface IAutoEntityUnionConstant { object Value { get; } IColumn Mapping { get; } } public class AutoEntityUnionConstant : IAutoEntityUnionConstant { public object Value { get; private set; } public IColumn Mapping { get; private set; } public AutoEntityUnionConstant(object value, IColumn mapping) { Value = value; Mapping = mapping; } } public interface IAutoEntityUnionMapping { IComplexColumn Source { get; } IColumn Target { get; } } public class AutoEntityUnionMapping : IAutoEntityUnionMapping { public IComplexColumn Source { get; private set; } public IColumn Target { get; private set; } public AutoEntityUnionMapping(IComplexColumn source, IColumn target) { Source = source; Target = target; } } public interface IAutoEntityUnionTable { Type Entity { get; } IFilter? Filter { get; } AutoEntityUnionConstant[] Constants { get; } AutoEntityUnionMapping[] Mappings { get; } } public class AutoEntityUnionTable : IAutoEntityUnionTable { public Type Entity => typeof(TEntity); public IFilter? Filter { get; } private List _constants = new List(); public AutoEntityUnionConstant[] Constants => _constants.ToArray(); private List _mappings = new List(); public AutoEntityUnionMapping[] Mappings => _mappings.ToArray(); public AutoEntityUnionTable(Filter? filter) { Filter = filter; } public AutoEntityUnionTable AddConstant(Expression> mapping, TType constant) { _constants.Add(new AutoEntityUnionConstant(constant, new Column(mapping))); return this; } public AutoEntityUnionTable AliasField(Expression> target, Expression> source) { var _tgt = new Column(target); var _node = new ComplexFormulaFieldNode(source); var _src = new ComplexColumn(_tgt.Property, _node); _mappings.Add(new AutoEntityUnionMapping(_src, _tgt)); return this; } public AutoEntityUnionTable AliasField(Expression> target, string formatString, params Expression>[] fields) { var _tgt = new Column(target); var _o = fields.Select(x => new ComplexFormulaFieldNode(x)); var _o2 = _o.OfType>().ToList() .Prepend(new ComplexFormulaConstantNode(formatString)) .ToArray(); var _n = new ComplexFormulaFormulaNode(_o2, FormulaOperator.Format); //var _node = new ComplexFormulaFieldNode(source); var _src = new ComplexColumn(_tgt.Property, _n); _mappings.Add(new AutoEntityUnionMapping(_src, _tgt)); return this; } } public abstract class AutoEntityUnionGenerator : IAutoEntityUnionGenerator { public AutoEntityUnionGenerator() { Configure(); } private List _tables = new List(); public IAutoEntityUnionTable[] Tables => _tables.ToArray(); public AutoEntityUnionTable AddTable(Filter? filter = null) { var table = new AutoEntityUnionTable(filter); _tables.Add(table); return table; } protected abstract void Configure(); public Type Definition => typeof(TInterface); public abstract bool Distinct { get; } public abstract Column[] IDColumns { get; } IColumn[] IAutoEntityGenerator.IDColumns => IDColumns; } }