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

lucaslorentz / auto-compute / 11763467169

10 Nov 2024 08:07AM UTC coverage: 77.292% (-12.0%) from 89.255%
11763467169

push

github

lucaslorentz
Add initial support for computed navigations and observers

168 of 433 new or added lines in 25 files covered. (38.8%)

7 existing lines in 5 files now uncovered.

1467 of 1898 relevant lines covered (77.29%)

109.86 hits per line

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

20.17
/src/LLL.AutoCompute.EFCore/Metadata/Internal/ComputedFactory.cs
1
using System.Linq.Expressions;
2
using LLL.AutoCompute.EFCore.Internal;
3
using Microsoft.EntityFrameworkCore.Metadata;
4

5
namespace LLL.AutoCompute.EFCore.Metadata.Internal;
6

7
public delegate Computed ComputedFactory<in TTarget>(
8
    IComputedExpressionAnalyzer<IEFCoreComputedInput> analyzer,
9
    TTarget target);
10

11
public class ComputedFactory
12
{
13
    public static ComputedFactory<IProperty> CreateComputedPropertyFactory<TEntity, TProperty>(
14
        Expression<Func<TEntity, TProperty>> computedExpression,
15
        IChangeCalculation<TProperty, TProperty> changeCalculation)
16
        where TEntity : class
17
    {
18
        return (analyzer, property) =>
12✔
19
        {
12✔
20
            try
12✔
21
            {
12✔
22
                if (property.DeclaringType.ClrType != typeof(TEntity))
18✔
23
                    throw new Exception($"Expected entity type {property.DeclaringType.ClrType} but got {typeof(TEntity)}");
12✔
24

12✔
25
                var changesProvider = analyzer.GetChangesProvider(
18✔
26
                    computedExpression,
18✔
27
                    default,
18✔
28
                    changeCalculation);
18✔
29

12✔
30
                if (!changesProvider.EntityContext.AllAccessedMembers.Any())
18✔
31
                    throw new Exception("Computed expression doesn't have tracked accessed members");
12✔
32

12✔
33
                return new ComputedProperty<TEntity, TProperty>(
18✔
34
                    property,
18✔
35
                    changesProvider);
18✔
36
            }
12✔
37
            catch (Exception ex)
12✔
38
            {
12✔
39
                throw new InvalidOperationException($"Invalid computed expression for '{property.DeclaringType.ShortName()}.{property.Name}': {ex.Message}", ex);
12✔
40
            }
12✔
41
        };
12✔
42
    }
43

44
    public static ComputedFactory<INavigationBase> CreateComputedNavigationFactory<TEntity, TProperty>(
45
        Expression<Func<TEntity, TProperty>> computedExpression,
46
        IChangeCalculation<TProperty, TProperty> changeCalculation)
47
        where TEntity : class
48
        where TProperty : class
49
    {
NEW
50
        return (analyzer, navigation) =>
×
NEW
51
        {
×
NEW
52
            try
×
NEW
53
            {
×
NEW
54
                if (navigation.DeclaringType.ClrType != typeof(TEntity))
×
NEW
55
                    throw new Exception($"Expected entity type {navigation.DeclaringType.ClrType} but got {typeof(TEntity)}");
×
NEW
56

×
NEW
57
                var changesProvider = analyzer.GetChangesProvider(
×
NEW
58
                    computedExpression,
×
NEW
59
                    default,
×
NEW
60
                    changeCalculation);
×
NEW
61

×
NEW
62
                if (!changesProvider.EntityContext.AllAccessedMembers.Any())
×
NEW
63
                    throw new Exception("Computed expression doesn't have tracked accessed members");
×
NEW
64

×
NEW
65
                return new ComputedNavigation<TEntity, TProperty>(
×
NEW
66
                    navigation,
×
NEW
67
                    changesProvider);
×
NEW
68
            }
×
NEW
69
            catch (Exception ex)
×
NEW
70
            {
×
NEW
71
                throw new InvalidOperationException($"Invalid computed expression for '{navigation.DeclaringType.ShortName()}.{navigation.Name}': {ex.Message}", ex);
×
NEW
72
            }
×
NEW
73
        };
×
74

75
    }
76
    public static ComputedFactory<INavigationBase> CreateComputedNavigationKeyFactory<TEntity, TProperty, TKey>(
77
        Expression<Func<TEntity, TKey>> computedExpression,
78
        IChangeCalculation<TKey, TKey> changeCalculation,
79
        Expression<Func<TProperty, TKey>> keyExpression)
80
        where TEntity : class
81
        where TProperty : class
82
    {
NEW
83
        return (analyzer, navigation) =>
×
NEW
84
        {
×
NEW
85
            try
×
NEW
86
            {
×
NEW
87
                if (navigation.DeclaringType.ClrType != typeof(TEntity))
×
NEW
88
                    throw new Exception($"Expected entity type {navigation.DeclaringType.ClrType} but got {typeof(TEntity)}");
×
NEW
89

×
NEW
90
                var changesProvider = analyzer.GetChangesProvider(
×
NEW
91
                    computedExpression,
×
NEW
92
                    default,
×
NEW
93
                    changeCalculation);
×
NEW
94

×
NEW
95
                if (!changesProvider.EntityContext.AllAccessedMembers.Any())
×
NEW
96
                    throw new Exception("Computed expression doesn't have tracked accessed members");
×
NEW
97

×
NEW
98
                return new ComputedNavigationKey<TEntity, TProperty, TKey>(
×
NEW
99
                    navigation,
×
NEW
100
                    changesProvider,
×
NEW
101
                    keyExpression);
×
NEW
102
            }
×
NEW
103
            catch (Exception ex)
×
NEW
104
            {
×
NEW
105
                throw new InvalidOperationException($"Invalid computed expression for '{navigation.DeclaringType.ShortName()}.{navigation.Name}': {ex.Message}", ex);
×
NEW
106
            }
×
NEW
107
        };
×
108
    }
109

110
    public static ComputedFactory<IPropertyBase> CreateComputedReactionFactory<TEntity, TProperty, TValue, TChange>(
111
        Expression<Func<TEntity, TValue>> computedExpression,
112
        IChangeCalculation<TValue, TChange> changeCalculation,
113
        Func<TProperty, TChange, TProperty> applyChange)
114
        where TEntity : class
115
    {
NEW
116
        return (analyzer, property) =>
×
NEW
117
        {
×
NEW
118
            try
×
NEW
119
            {
×
NEW
120
                if (property.DeclaringType.ClrType != typeof(TEntity))
×
NEW
121
                    throw new Exception($"Expected entity type {property.DeclaringType.ClrType} but got {typeof(TEntity)}");
×
NEW
122

×
NEW
123
                var changesProvider = analyzer.GetChangesProvider(
×
NEW
124
                    computedExpression,
×
NEW
125
                    default,
×
NEW
126
                    changeCalculation);
×
NEW
127

×
NEW
128
                if (!changesProvider.EntityContext.AllAccessedMembers.Any())
×
NEW
129
                    throw new Exception("Computed expression doesn't have tracked accessed members");
×
NEW
130

×
NEW
131
                return new ComputedReaction<TEntity, TProperty, TChange>(
×
NEW
132
                    property,
×
NEW
133
                    changesProvider,
×
NEW
134
                    applyChange);
×
NEW
135
            }
×
NEW
136
            catch (Exception ex)
×
NEW
137
            {
×
NEW
138
                throw new InvalidOperationException($"Invalid computed expression for '{property.DeclaringType.ShortName()}.{property.Name}': {ex.Message}", ex);
×
NEW
139
            }
×
NEW
140
        };
×
141
    }
142

143
    public static ComputedFactory<IEntityType> CreateComputedObserverFactory<TEntity, TValue, TChange>(
144
        Expression<Func<TEntity, TValue>> computedExpression,
145
        IChangeCalculation<TValue, TChange> changeCalculation,
146
        Func<ComputedChangeEventData<TEntity, TChange>, Task> callback)
147
        where TEntity : class
148
    {
NEW
149
        return (analyzer, entityType) =>
×
NEW
150
        {
×
NEW
151
            try
×
NEW
152
            {
×
NEW
153
                var changesProvider = analyzer.GetChangesProvider(
×
NEW
154
                    computedExpression,
×
NEW
155
                    default,
×
NEW
156
                    changeCalculation);
×
NEW
157

×
NEW
158
                if (!changesProvider.EntityContext.AllAccessedMembers.Any())
×
NEW
159
                    throw new Exception("Computed expression doesn't have tracked accessed members");
×
NEW
160

×
NEW
161
                return new ComputedObserver<TEntity, TChange>(
×
NEW
162
                    changesProvider,
×
NEW
163
                    callback);
×
NEW
164
            }
×
NEW
165
            catch (Exception ex)
×
NEW
166
            {
×
NEW
167
                throw new InvalidOperationException($"Invalid computed expression for reaction in '{entityType.Name}': {ex.Message}", ex);
×
NEW
168
            }
×
NEW
169
        };
×
170
    }
171
}
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