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

lucaslorentz / auto-compute / 11755625072

09 Nov 2024 10:48AM UTC coverage: 79.945% (-0.09%) from 80.033%
11755625072

push

github

lucaslorentz
Add initial support for computed navigations and observers

159 of 359 new or added lines in 22 files covered. (44.29%)

41 existing lines in 7 files now uncovered.

1459 of 1825 relevant lines covered (79.95%)

113.62 hits per line

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

25.53
/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<IPropertyBase> CreateComputedReactionFactory<TEntity, TProperty, TValue, TChange>(
77
        Expression<Func<TEntity, TValue>> computedExpression,
78
        IChangeCalculation<TValue, TChange> changeCalculation,
79
        Func<TProperty, TChange, TProperty> applyChange)
80
        where TEntity : class
81
    {
NEW
82
        return (analyzer, property) =>
×
NEW
83
        {
×
NEW
84
            try
×
NEW
85
            {
×
NEW
86
                if (property.DeclaringType.ClrType != typeof(TEntity))
×
NEW
87
                    throw new Exception($"Expected entity type {property.DeclaringType.ClrType} but got {typeof(TEntity)}");
×
NEW
88

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

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

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

109
    public static ComputedFactory<IEntityType> CreateComputedObserverFactory<TEntity, TValue, TChange>(
110
        Expression<Func<TEntity, TValue>> computedExpression,
111
        IChangeCalculation<TValue, TChange> changeCalculation,
112
        Func<ComputedChangeEventData<TEntity, TChange>, Task> callback)
113
        where TEntity : class
114
    {
NEW
115
        return (analyzer, entityType) =>
×
NEW
116
        {
×
NEW
117
            try
×
NEW
118
            {
×
NEW
119
                var changesProvider = analyzer.GetChangesProvider(
×
NEW
120
                    computedExpression,
×
NEW
121
                    default,
×
NEW
122
                    changeCalculation);
×
NEW
123

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

×
NEW
127
                return new ComputedObserver<TEntity, TChange>(
×
NEW
128
                    changesProvider,
×
NEW
129
                    callback);
×
NEW
130
            }
×
NEW
131
            catch (Exception ex)
×
NEW
132
            {
×
NEW
133
                throw new InvalidOperationException($"Invalid computed expression for reaction in '{entityType.Name}': {ex.Message}", ex);
×
NEW
134
            }
×
NEW
135
        };
×
136
    }
137
}
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