aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.BL/Builders/EntityBuilderBase.cs
blob: 37ec2ae5c0234c598f58d42b821af900ef9a0c01 (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
116
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace Tango.BL.Builders
{
    public abstract class EntityBuilderBase<T, TBuilder> : IEntityBuilder<T> where T : ObservableEntity<T> where TBuilder : EntityBuilderBase<T, TBuilder>
    {
        private List<KeyValuePair<int, Action>> _steps;
        private bool _entity_set;

        protected T Entity { get; set; }
        protected ObservablesContext Context { get; set; }

        public EntityBuilderBase(ObservablesContext context)
        {
            _steps = new List<KeyValuePair<int, Action>>();
            Context = context;
        }

        public virtual TBuilder Set(Expression<Func<T, bool>> condition)
        {
            ThrowIfEntitySet();

            AddStep(0, () =>
             {
                 IQueryable<T> query = Context.Set<T>().Where(condition);
                 query = OnSetQuery(query);
                 Entity = query.FirstOrDefault();
             });

            _entity_set = true;

            return this as TBuilder;
        }

        public virtual TBuilder SetFirst()
        {
            ThrowIfEntitySet();

            AddStep(0, () =>
            {
                IQueryable<T> query = Context.Set<T>();
                query = OnSetQuery(query);
                Entity = query.FirstOrDefault();
            });

            _entity_set = true;

            return this as TBuilder;
        }

        public virtual TBuilder Set(T entity)
        {
            ThrowIfEntitySet();

            Entity = entity;
            _entity_set = true;
            return this as TBuilder;
        }

        public TBuilder Set(string guid)
        {
            return Set(x => x.Guid == guid);
        }

        private void ThrowIfEntitySet()
        {
            if (_entity_set) throw new InvalidOperationException("Could not set entity. Entity was already set.");
        }

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

        protected TBuilder AddStep(int index, Action action)
        {
            _steps.Add(new KeyValuePair<int, Action>(index, action));
            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);
            }
        }

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

            CommitSteps();

            return Entity;
        }

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