using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Tango.Core; namespace Tango.BL.Builders { public class EntityCollectionBuilderBase : IEntityCollectionBuilder where T : ObservableEntity where TBuilder : EntityCollectionBuilderBase { private List> _steps; private List, IQueryable>>> _querySteps; private bool _entity_set; private Func, IQueryable> _appendQuery; protected IEnumerable Entities { get; set; } protected ObservablesContext Context { get; set; } public EntityCollectionBuilderBase(ObservablesContext context) { Entities = new List(); _steps = new List>(); _querySteps = new List, IQueryable>>>(); Context = context; } public virtual TBuilder SetAll() { AddStep(0, () => { IQueryable query = Context.Set(); query = OnSetQuery(query); foreach (var queryStep in _querySteps.ToList().DistinctBy(x => x.Key).OrderBy(x => x.Key)) { query = queryStep.Value(query); } if (_appendQuery != null) { query = _appendQuery(query); } Entities = query.ToList(); }); _entity_set = true; return this as TBuilder; } public virtual TBuilder Set(Expression> condition) { AddStep(0, () => { IQueryable query = Context.Set().Where(condition); query = OnSetQuery(query); foreach (var queryStep in _querySteps.ToList().DistinctBy(x => x.Key).OrderBy(x => x.Key)) { query = queryStep.Value(query); } if (_appendQuery != null) { query = _appendQuery(query); } Entities = query.ToList(); }); _entity_set = true; return this as TBuilder; } protected virtual IQueryable OnSetQuery(IQueryable query) { return query; } public TBuilder Query(Func, IQueryable> query) { _appendQuery = query; return this as TBuilder; } protected void CommitSteps() { foreach (var step in _steps.ToList().DistinctBy(x => x.Key).OrderBy(x => x.Key)) { step.Value(); _steps.Remove(step); } } protected TBuilder AddStep(int index, Action action) { _steps.Add(new KeyValuePair(index, action)); return this as TBuilder; } protected TBuilder AddQueryStep(int index, Func, IQueryable> func) { _querySteps.Add(new KeyValuePair, IQueryable>>(index, func)); return this as TBuilder; } public SynchronizedObservableCollection Build() { if (!_entity_set) { throw new InvalidOperationException("Could not build entity. Entity was not set."); } CommitSteps(); return Entities.ToSynchronizedObservableCollection(); } public List BuildList() { if (!_entity_set) { throw new InvalidOperationException("Could not build entity. Entity was not set."); } CommitSteps(); return Entities.ToList(); } public Task> BuildAsync() { return Task.Factory.StartNew>(() => { return Build(); }); } public Task> BuildListAsync() { return Task.Factory.StartNew>(() => { return BuildList(); }); } } }