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

lucaslorentz / auto-compute / 11750808709

08 Nov 2024 11:01PM UTC coverage: 81.803% (+0.4%) from 81.44%
11750808709

push

github

lucaslorentz
Add initial support for computed navigations and observers

151 of 309 new or added lines in 14 files covered. (48.87%)

12 existing lines in 5 files now uncovered.

1452 of 1775 relevant lines covered (81.8%)

116.37 hits per line

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

91.49
/src/LLL.AutoCompute.EFCore/Internal/EFCoreEntityProperty.cs
1
using System.Linq.Expressions;
2
using System.Reflection;
3
using Microsoft.EntityFrameworkCore;
4
using Microsoft.EntityFrameworkCore.Metadata;
5

6
namespace LLL.AutoCompute.EFCore.Internal;
7

8
public abstract class EFCoreEntityProperty(IProperty property)
11✔
9
    : EFCoreEntityMember
10
{
11
    public override IPropertyBase PropertyBase => property;
20✔
12
    public IProperty Property => property;
599✔
13
}
14

15
public class EFCoreEntityProperty<TEntity>(
16
    IProperty property
17
) : EFCoreEntityProperty(property),
11✔
18
    IEntityProperty<IEFCoreComputedInput, TEntity>
19
    where TEntity : class
20
{
UNCOV
21
    public virtual string Name => Property.Name;
×
22

23
    public virtual string ToDebugString()
24
    {
UNCOV
25
        return $"{Property.DeclaringType.ShortName()}.{Property.Name}";
×
26
    }
27

28
    public virtual Expression CreateOriginalValueExpression(
29
        IEntityMemberAccess<IEntityProperty> memberAccess,
30
        Expression inputExpression)
31
    {
32
        return Expression.Convert(
36✔
33
            Expression.Call(
36✔
34
                Expression.Constant(this),
36✔
35
                GetType().GetMethod(nameof(GetOriginalValue), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)!,
36✔
36
                inputExpression,
36✔
37
                memberAccess.FromExpression
36✔
38
            ),
36✔
39
            Property.ClrType
36✔
40
        );
36✔
41
    }
42

43
    public virtual Expression CreateCurrentValueExpression(
44
        IEntityMemberAccess<IEntityProperty> memberAccess,
45
        Expression inputExpression)
46
    {
47
        return Expression.Convert(
36✔
48
            Expression.Call(
36✔
49
                Expression.Constant(this),
36✔
50
                GetType().GetMethod(nameof(GetCurrentValue), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)!,
36✔
51
                inputExpression,
36✔
52
                memberAccess.FromExpression
36✔
53
            ),
36✔
54
            Property.ClrType
36✔
55
        );
36✔
56
    }
57

58
    public Expression CreateIncrementalOriginalValueExpression(
59
        IEntityMemberAccess<IEntityProperty> memberAccess,
60
        Expression inputExpression,
61
        Expression incrementalContextExpression)
62
    {
63
        return CreateOriginalValueExpression(memberAccess, inputExpression);
10✔
64
    }
65

66
    public Expression CreateIncrementalCurrentValueExpression(
67
        IEntityMemberAccess<IEntityProperty> memberAccess,
68
        Expression inputExpression,
69
        Expression incrementalContextExpression)
70
    {
71
        return CreateCurrentValueExpression(memberAccess, inputExpression);
10✔
72
    }
73

74
    protected virtual object? GetOriginalValue(IEFCoreComputedInput input, TEntity ent)
75
    {
76
        var dbContext = input.DbContext;
54✔
77

78
        var entityEntry = dbContext.Entry(ent!);
54✔
79

80
        if (entityEntry.State == EntityState.Added)
54✔
UNCOV
81
            throw new Exception($"Cannot access property '{Property.DeclaringType.ShortName()}.{Property.Name}' original value for an added entity");
×
82

83
        return entityEntry.Property(Property).OriginalValue;
54✔
84
    }
85

86
    protected virtual object? GetCurrentValue(IEFCoreComputedInput input, TEntity ent)
87
    {
88
        var dbContext = input.DbContext;
135✔
89

90
        var entityEntry = dbContext.Entry(ent!);
135✔
91

92
        if (entityEntry.State == EntityState.Deleted)
135✔
UNCOV
93
            throw new Exception($"Cannot access property '{Property.DeclaringType.ShortName()}.{Property.Name}' current value for a deleted entity");
×
94

95
        return entityEntry.Property(Property).CurrentValue;
135✔
96
    }
97

98
    public virtual async Task<IReadOnlyCollection<TEntity>> GetAffectedEntitiesAsync(IEFCoreComputedInput input, IncrementalContext incrementalContext)
99
    {
100
        var affectedEntities = new HashSet<TEntity>();
175✔
101
        foreach (var entityEntry in input.EntityEntriesOfType(Property.DeclaringType))
760✔
102
        {
103
            if (entityEntry.State == EntityState.Added
205✔
104
                || entityEntry.State == EntityState.Deleted
205✔
105
                || entityEntry.State == EntityState.Modified)
205✔
106
            {
107
                var propertyEntry = entityEntry.Property(Property);
163✔
108
                if (entityEntry.State == EntityState.Added
163✔
109
                    || entityEntry.State == EntityState.Deleted
163✔
110
                    || propertyEntry.IsModified)
163✔
111
                {
112
                    affectedEntities.Add((TEntity)entityEntry.Entity);
123✔
113
                }
114
            }
115
        }
116
        return affectedEntities;
175✔
117
    }
118
}
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