< Summary - ZhEaIsNsAaBn.Libraries coverage (affected: 23 packages)

Information
Class: Microsoft.EntityFrameworkCore.AuditedUpdateSetters<T>
Assembly: ZhEaIsNsAaBn.Infrastructure.Core
File(s): /home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/DataBasePackages/ZhEaIsNsAaBn.Infrastructure.Core/Auditing/AuditedUpdateSetters.cs
Line coverage
97%
Covered lines: 36
Uncovered lines: 1
Coverable lines: 37
Total lines: 124
Line coverage: 97.2%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor()100%11100%
SetProperty(...)100%11100%
SetProperty(...)100%11100%
SetAuditValue(...)100%11100%
get_Count()100%210%
Execute(...)100%11100%
ExecuteAsync(...)100%11100%
Apply(...)100%22100%
Execute(...)100%11100%
ExecuteAsync(...)100%11100%
Build()100%22100%
.cctor()100%11100%
Find(...)100%11100%
.cctor()100%11100%

File(s)

/home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/DataBasePackages/ZhEaIsNsAaBn.Infrastructure.Core/Auditing/AuditedUpdateSetters.cs

#LineLine coverage
 1using System.Reflection;
 2using System.Runtime.CompilerServices;
 3using Microsoft.EntityFrameworkCore.Query;
 4
 5// ReSharper disable once CheckNamespace
 6namespace Microsoft.EntityFrameworkCore;
 7
 8/// <summary>
 9/// The columns an <c>AuditedExecuteUpdate[Async]</c> sets, besides the audit fields. One shape for both EF versions: EF
 10/// expression over <c>SetPropertyCalls&lt;T&gt;</c>, EF 10 an <c>Action&lt;UpdateSettersBuilder&lt;T&gt;&gt;</c>; this 
 11/// </summary>
 12/// <typeparam name="TEntity">The entity type.</typeparam>
 13public sealed class AuditedUpdateSetters< TEntity >
 14    where TEntity : class
 15{
 16#if NET10_0_OR_GREATER
 1217    private readonly List<Action<UpdateSettersBuilder<TEntity>>> _setters = [];
 18#else
 1219    private readonly List<Func<Expression, Expression>> _setters = [];
 20#endif
 21
 22
 4823    internal AuditedUpdateSetters() { }
 24
 25
 26    /// <summary>Sets <paramref name="property"/> to <paramref name="value"/> (sent as a parameter).</summary>
 27    /// <typeparam name="TProperty">The property type.</typeparam>
 28    /// <param name="property">The property, e.g. <c>o =&gt; o.Status</c>.</param>
 29    /// <param name="value">The new value.</param>
 30    /// <returns>These setters.</returns>
 31    /// <exception cref="ArgumentNullException"><paramref name="property"/> is <see langword="null"/>.</exception>
 32    public AuditedUpdateSetters<TEntity> SetProperty< TProperty >( Expression<Func<TEntity, TProperty>> property, TPrope
 33    {
 11634        ArgumentNullException.ThrowIfNull( property );
 35
 36#if NET10_0_OR_GREATER
 5837        _setters.Add( builder => builder.SetProperty( property, value ) );
 38#else
 39        // A field of a constant box, so EF sends a parameter instead of inlining a literal.
 5840        Expression boxed = Expression.Field( Expression.Constant( new StrongBox<TProperty>( value ) ), nameof( StrongBox
 41
 5842        _setters.Add( calls => Expression.Call( calls, Ef9.SetValue.MakeGenericMethod( typeof( TProperty ) ), property, 
 43#endif
 44
 11645        return this;
 46    }
 47
 48    /// <summary>Sets <paramref name="property"/> from an expression over the row, e.g. <c>o =&gt; o.Count + 1</c>.</sum
 49    /// <typeparam name="TProperty">The property type.</typeparam>
 50    /// <param name="property">The property.</param>
 51    /// <param name="value">The value expression.</param>
 52    /// <returns>These setters.</returns>
 53    /// <exception cref="ArgumentNullException">An argument is <see langword="null"/>.</exception>
 54    public AuditedUpdateSetters<TEntity> SetProperty< TProperty >( Expression<Func<TEntity, TProperty>> property, Expres
 55    {
 456        ArgumentNullException.ThrowIfNull( property );
 457        ArgumentNullException.ThrowIfNull( value );
 58
 59#if NET10_0_OR_GREATER
 260        _setters.Add( builder => builder.SetProperty( property, value ) );
 61#else
 262        _setters.Add( calls => Expression.Call( calls, Ef9.SetExpression.MakeGenericMethod( typeof( TProperty ) ), prope
 63#endif
 64
 465        return this;
 66    }
 67
 68
 69    /// <summary>Adds <c>row.Property = value</c> for an audit column whose type is only known at run time.</summary>
 70    internal void SetAuditValue( PropertyInfo property, object? value )
 71    {
 10872        var row    = Expression.Parameter( typeof( TEntity ), "e" );
 10873        var lambda = Expression.Lambda( typeof( Func<,> ).MakeGenericType( typeof( TEntity ), property.PropertyType ), E
 74
 10875        SetValueMethod.MakeGenericMethod( property.PropertyType ).Invoke( this, [ lambda, value ] );
 10876    }
 77
 078    internal int Count => _setters.Count;
 79
 80#if NET10_0_OR_GREATER
 481    internal int Execute( IQueryable<TEntity> query ) => query.ExecuteUpdate( Apply );
 82
 883    internal Task<int> ExecuteAsync( IQueryable<TEntity> query, CancellationToken cancellationToken ) => query.ExecuteUp
 84
 85    private void Apply( UpdateSettersBuilder<TEntity> builder )
 86    {
 20487        foreach ( var setter in _setters ) { setter( builder ); }
 1288    }
 89#else
 490    internal int Execute( IQueryable<TEntity> query ) => query.ExecuteUpdate( Build() );
 91
 892    internal Task<int> ExecuteAsync( IQueryable<TEntity> query, CancellationToken cancellationToken ) => query.ExecuteUp
 93
 94    private Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> Build()
 95    {
 1296        var        calls = Expression.Parameter( typeof( SetPropertyCalls<TEntity> ), "s" );
 1297        Expression body  = calls;
 98
 20499        foreach ( var setter in _setters ) { body = setter( body ); }
 100
 101
 12102        return Expression.Lambda<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>>( body, calls );
 103    }
 104
 105    /// The two EF 9 <c>SetPropertyCalls&lt;T&gt;.SetProperty&lt;P&gt;</c> overloads: ( Func&lt;T, P&gt;, P ) and ( Func
 106    private static class Ef9
 107    {
 4108        internal static readonly MethodInfo SetValue = Find( valueIsExpression: false );
 109
 4110        internal static readonly MethodInfo SetExpression = Find( valueIsExpression: true );
 111
 112
 113        private static MethodInfo Find( bool valueIsExpression )
 8114            => typeof( SetPropertyCalls<TEntity> ).GetMethods()
 8115                                                  .Single( m => m.Name == nameof( SetPropertyCalls<TEntity>.SetProperty 
 8116                                                                && m.GetParameters().Length == 2
 8117                                                                && m.GetParameters()[ 1 ].ParameterType.IsGenericParamet
 118    }
 119#endif
 120
 8121    private static readonly MethodInfo SetValueMethod = typeof( AuditedUpdateSetters<TEntity> ).GetMethods()
 8122                                                                                                   .Single( m => m.Name 
 8123                                                                                                                 && m.Ge
 124}