• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lucaslorentz / auto-compute / 18743477386

23 Oct 2025 01:20AM UTC coverage: 83.516% (+0.2%) from 83.356%
18743477386

push

github

lucaslorentz
Optimise incremental context enrichment

4 of 4 new or added lines in 1 file covered. (100.0%)

3 existing lines in 2 files now uncovered.

1829 of 2190 relevant lines covered (83.52%)

864.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.36
/src/LLL.AutoCompute/EntityContexts/EntityContext.cs
1
using System.Linq.Expressions;
2

3
namespace LLL.AutoCompute.EntityContexts;
4

5
public abstract class EntityContext
6
{
7
    private readonly Expression _expression;
8
    private readonly IReadOnlyList<EntityContext> _parents;
9
    private readonly HashSet<IObservedMember> _observedMembers = [];
842✔
10
    private readonly IList<EntityContext> _childContexts = [];
842✔
11

12
    public EntityContext(Expression expression, IReadOnlyList<EntityContext> parents)
842✔
13
    {
14
        _expression = expression;
842✔
15
        _parents = parents;
842✔
16

17
        foreach (var parent in parents)
2,528✔
18
            parent._childContexts.Add(this);
422✔
19
    }
20

21
    public IReadOnlyList<EntityContext> Parents => _parents;
132✔
22
    public IReadOnlySet<IObservedMember> ObservedMembers => _observedMembers;
80✔
UNCOV
23
    public IEnumerable<EntityContext> ChildContexts => _childContexts;
×
24

25
    public abstract IObservedEntityType EntityType { get; }
26
    public abstract bool IsTrackingChanges { get; }
27
    public Guid Id { get; } = Guid.NewGuid();
842✔
UNCOV
28
    public Expression Expression => _expression;
×
29

30
    public void RegisterObservedMember(IObservedMember member)
31
    {
32
        _observedMembers.Add(member);
448✔
33
    }
34

35
    public IEnumerable<IObservedMember> GetAllObservedMembers()
36
    {
37
        foreach (var om in _observedMembers)
9,940✔
38
            yield return om;
1,752✔
39

40
        foreach (var cc in _childContexts)
7,582✔
41
        {
42
            foreach (var om in cc.GetAllObservedMembers())
5,920✔
43
            {
44
                yield return om;
1,722✔
45
            }
46
        }
47
    }
48

49
    public async Task<IReadOnlyCollection<object>> GetAffectedEntitiesAsync(object input, IncrementalContext incrementalContext)
50
    {
51
        var entities = new HashSet<object>();
5,090✔
52

53
        foreach (var member in _observedMembers)
17,900✔
54
        {
55
            if (member is IObservedProperty observedProperty)
3,860✔
56
            {
57
                var propertyChanges = await observedProperty.GetChangesAsync(input);
2,628✔
58
                foreach (var ent in propertyChanges.GetEntityChanges())
11,860✔
59
                {
60
                    if (!EntityType.IsInstanceOfType(ent))
3,302✔
61
                        continue;
62

63
                    entities.Add(ent);
3,302✔
64
                }
65
            }
66
            else if (member is IObservedNavigation observedNavigation)
1,232✔
67
            {
68
                var navigationChanges = await observedNavigation.GetChangesAsync(input);
1,232✔
69
                foreach (var (entity, changes) in navigationChanges.GetEntityChanges())
4,560✔
70
                {
71
                    if (!EntityType.IsInstanceOfType(entity))
1,048✔
72
                        continue;
73

74
                    entities.Add(entity);
1,048✔
75
                    foreach (var addedEntity in changes.Added)
4,004✔
76
                    {
77
                        incrementalContext.SetShouldLoadAll(addedEntity);
954✔
78
                        incrementalContext.AddCurrentEntity(entity, observedNavigation, addedEntity);
954✔
79
                    }
80
                    foreach (var removedEntity in changes.Removed)
2,304✔
81
                    {
82
                        incrementalContext.SetShouldLoadAll(removedEntity);
104✔
83
                        incrementalContext.AddOriginalEntity(entity, observedNavigation, removedEntity);
104✔
84
                    }
85
                }
86
            }
87
        }
88

89
        foreach (var childContext in _childContexts)
16,784✔
90
        {
91
            var ents = await childContext.GetParentAffectedEntities(input, incrementalContext);
3,302✔
92
            foreach (var ent in ents)
10,464✔
93
            {
94
                if (!EntityType.IsInstanceOfType(ent))
1,930✔
95
                    continue;
96

97
                entities.Add(ent);
1,930✔
98
            }
99
        }
100

101
        return entities;
5,090✔
102
    }
103

104
    public abstract Task<IReadOnlyCollection<object>> GetParentAffectedEntities(object input, IncrementalContext incrementalContext);
105

106
    public virtual async Task EnrichIncrementalContextAsync(object input, IReadOnlyCollection<object> entities, IncrementalContext incrementalContext)
107
    {
108
        foreach (var childContext in _childContexts)
2,840✔
109
            await childContext.EnrichIncrementalContextFromParentAsync(input, entities, incrementalContext);
618✔
110
    }
111

112
    public virtual async Task EnrichIncrementalContextFromParentAsync(object input, IReadOnlyCollection<object> parentEntities, IncrementalContext incrementalContext)
113
    {
114
        await EnrichIncrementalContextAsync(input, parentEntities, incrementalContext);
358✔
115
    }
116

117
    public virtual async Task EnrichIncrementalContextTowardsRootAsync(object input, IReadOnlyCollection<object> entities, IncrementalContext incrementalContext)
118
    {
119
        foreach (var parent in Parents)
432✔
120
            await parent.EnrichIncrementalContextTowardsRootAsync(input, entities, incrementalContext);
96✔
121
    }
122

123
    public virtual async Task PreLoadNavigationsAsync(object input, IReadOnlyCollection<object> entities)
124
    {
125
        foreach (var childContext in _childContexts)
19,000✔
126
            await childContext.PreLoadNavigationsFromParentAsync(input, entities);
2,700✔
127
    }
128

129
    public virtual async Task PreLoadNavigationsFromParentAsync(object input, IReadOnlyCollection<object> parentEntities)
130
    {
131
        await PreLoadNavigationsAsync(input, parentEntities);
1,416✔
132
    }
133

134
    public virtual void MarkNavigationToLoadAll()
135
    {
136
        foreach (var parent in Parents)
36✔
137
            parent.MarkNavigationToLoadAll();
6✔
138
    }
139

140
    public void ValidateAll()
141
    {
142
        ValidateSelf();
878✔
143

144
        foreach (var childContext in _childContexts)
2,616✔
145
            childContext.ValidateAll();
430✔
146
    }
147

148
    public virtual void ValidateSelf() { }
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc