aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.BL/Builders/EntityCollectionBuilderBase.cs
blob: a0cd2451102f85e3d8ae4233a3a89e714e02fa8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
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<T, TBuilder> : IEntityCollectionBuilder<T> where T : ObservableEntity<T> where TBuilder : EntityCollectionBuilderBase<T, TBuilder>
    {
        private List<KeyValuePair<int, Action>> _steps;
        private List<KeyValuePair<int, Func<IQueryable<T>, IQueryable<T>>>> _querySteps;
        private bool _entity_set;

        protected IEnumerable<T> Entities { get; set; }

        protected ObservablesContext Context { get; set; }

        public EntityCollectionBuilderBase(ObservablesContext context)
        {
            Entities = new List<T>();
            _steps = new List<KeyValuePair<int, Action>>();
            _querySteps = new List<KeyValuePair<int, Func<IQueryable<T>, IQueryable<T>>>>();
            Context = context;
        }

        public virtual TBuilder SetAll()
        {
            AddStep(0, () =>
            {
                IQueryable<T> query = Context.Set<T>();
                query = OnSetQuery(query);

                foreach (var queryStep in _querySteps.ToList().DistinctBy(x => x.Key).OrderBy(x => x.Key))
                {
                    query = queryStep.Value(query);
                }

                Entities = query.ToList();
            });

            _entity_set = true;

            return this as TBuilder;
        }

        public virtual TBuilder Set(Expression<Func<T, bool>> condition)
        {
            AddStep(0, () =>
            {
                IQueryable<T> query = Context.Set<T>().Where(condition);
                query = OnSetQuery(query);

                foreach (var queryStep in _querySteps.ToList().DistinctBy(x => x.Key).OrderBy(x => x.Key))
                {
                    query = queryStep.Value(query);
                }

                Entities = query.ToList();
            });

            _entity_set = true;

            return this as TBuilder;
        }

        protected virtual IQueryable<T> OnSetQuery(IQueryable<T> query)
        {
            return query;
        }

        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<int, Action>(index, action));
            return this as TBuilder;
        }

        protected TBuilder AddQueryStep(int index, Func<IQueryable<T>, IQueryable<T>> func)
        {
            _querySteps.Add(new KeyValuePair<int, Func<IQueryable<T>, IQueryable<T>>>(index, func));
            return this as TBuilder;
        }

        public SynchronizedObservableCollection<T> Build()
        {
            if (!_entity_set)
            {
                throw new InvalidOperationException("Could not build entity. Entity was not set.");
            }

            CommitSteps();

            return Entities.ToSynchronizedObservableCollection();
        }

        public Task<SynchronizedObservableCollection<T>> BuildAsync()
        {
            return Task.Factory.StartNew<SynchronizedObservableCollection<T>>(() =>
            {
                return Build();
            });
        }
    }
}