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

lucaslorentz / auto-compute / 23084514956

14 Mar 2026 08:43AM UTC coverage: 59.695% (-20.4%) from 80.097%
23084514956

push

github

web-flow
Merge pull request #19 from lucaslorentz/feature/migration-backfill

Automatic backfill SQL generation in migrations

21 of 148 new or added lines in 8 files covered. (14.19%)

6 existing lines in 2 files now uncovered.

1995 of 3342 relevant lines covered (59.69%)

663.35 hits per line

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

93.33
/src/LLL.AutoCompute.EFCore/Extensions/EntityTypeBuilderExtensions.cs
1
using System.Linq.Expressions;
2
using System.Text.RegularExpressions;
3
using LLL.AutoCompute.EFCore.Metadata.Internal;
4
using Microsoft.EntityFrameworkCore.Metadata.Builders;
5

6
namespace LLL.AutoCompute.EFCore;
7

8
public static class EntityTypeBuilderExtensions
9
{
10
    private static readonly Regex ValidNameRegex = new(@"^[A-Z][a-zA-Z0-9]*$", RegexOptions.Compiled);
2✔
11

12
    public static PropertyBuilder<TProperty> ComputedProperty<TEntity, TProperty>(
13
        this EntityTypeBuilder<TEntity> entityTypeBuilder,
14
        Expression<Func<TEntity, TProperty>> propertyExpression,
15
        Expression<Func<TEntity, TProperty>> computedExpression,
16
        ChangeCalculatorSelector<TProperty, TProperty>? calculationSelector = null)
17
        where TEntity : class
18
    {
19
        return entityTypeBuilder.Property(propertyExpression)
246✔
20
            .AutoCompute(computedExpression, calculationSelector);
246✔
21
    }
22

23
    public static NavigationBuilder<TEntity, TProperty> ComputedNavigation<TEntity, TProperty>(
24
        this EntityTypeBuilder<TEntity> entityTypeBuilder,
25
        Expression<Func<TEntity, TProperty>> navigationExpression,
26
        Expression<Func<TEntity, TProperty>> computedExpression,
27
        ChangeCalculatorSelector<TProperty, TProperty>? calculationSelector = null,
28
        Action<IComputedNavigationBuilder<TEntity, TProperty>>? configure = null)
29
        where TEntity : class
30
        where TProperty : class
31
    {
32
        return entityTypeBuilder.Navigation(navigationExpression!)
3✔
33
            .AutoCompute(computedExpression!, calculationSelector, configure);
3✔
34
    }
35

36
    public static void ComputedObserver<TEntity, TValue, TChange>(
37
        this EntityTypeBuilder<TEntity> entityTypeBuilder,
38
        string name,
39
        Expression<Func<TEntity, TValue>> computedExpression,
40
        Expression<Func<TEntity, bool>>? filterExpression,
41
        ChangeCalculatorSelector<TValue, TChange> calculationSelector,
42
        Func<TEntity, TChange, Task> callback)
43
        where TEntity : class
44
    {
45
        entityTypeBuilder
18✔
46
            .ComputedObserver(
18✔
47
                name,
18✔
48
                computedExpression,
18✔
49
                filterExpression,
18✔
50
                calculationSelector,
18✔
51
                async (ComputedChangeEventData<TEntity, TChange> eventData) =>
18✔
52
                {
18✔
53
                    foreach (var (entity, change) in eventData.Changes)
130✔
54
                    {
18✔
55
                        await callback(entity, change);
50✔
56
                    }
18✔
57
                }
18✔
58
            );
18✔
59
    }
60

61
    public static void ComputedObserver<TEntity, TValue, TChange>(
62
        this EntityTypeBuilder<TEntity> entityTypeBuilder,
63
        string name,
64
        Expression<Func<TEntity, TValue>> computedExpression,
65
        Expression<Func<TEntity, bool>>? filterExpression,
66
        ChangeCalculatorSelector<TValue, TChange> calculationSelector,
67
        Func<ComputedChangeEventData<TEntity, TChange>, Task> callback)
68
        where TEntity : class
69
    {
70
        if (!ValidNameRegex.IsMatch(name))
18✔
UNCOV
71
            throw new ArgumentException($"Observer name '{name}' is invalid. Name must be PascalCase with only alphanumeric characters (e.g. 'NotificarBiker').", nameof(name));
×
72

73
        var changeCalculator = calculationSelector(ChangeCalculatorFactory<TValue>.Instance);
18✔
74

75
        entityTypeBuilder.Metadata.AddObserverFactory(
18✔
76
            ComputedObserverFactory.CreateObserverFactory(
18✔
77
                name,
18✔
78
                computedExpression,
18✔
79
                filterExpression,
18✔
80
                changeCalculator,
18✔
81
                callback));
18✔
82
    }
83

84
    public static void ConsistencyFilter<TEntity>(
85
        this EntityTypeBuilder<TEntity> entityTypeBuilder,
86
        Expression<Func<TEntity, DateTime, bool>> filter)
87
        where TEntity : class
88
    {
UNCOV
89
        entityTypeBuilder.Metadata.SetConsistencyFilter(filter);
×
90
    }
91
}
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