< Summary

Information
Class: MyNet.UI.ViewModels.List.Filtering.Filters.NullableComparableFilterViewModel<T1, T2>
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/List/Filtering/Filters/NullableComparableFilterViewModel.cs
Tag: 323_28699572109
Line coverage
0%
Covered lines: 0
Uncovered lines: 49
Coverable lines: 49
Total lines: 141
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 35
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
set_Operator(...)100%210%
set_From(...)100%210%
set_To(...)100%210%
set_Minimum(...)100%210%
set_Maximum(...)100%210%
get_IsEmpty()0%4260%
BuildExpressionCore()0%870290%
Reset()100%210%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/List/Filtering/Filters/NullableComparableFilterViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="NullableComparableFilterViewModel.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Linq.Expressions;
 9using MyNet.Primitives;
 10
 11namespace MyNet.UI.ViewModels.List.Filtering.Filters;
 12
 13/// <summary>
 14/// Filter view model for nullable comparable properties (int?, DateTime?, double?, etc.).
 15/// Supports range filtering (from/to) and various comparison operators including IsBetween.
 16/// Null property values are excluded from match unless operator is specifically checking for null.
 17/// </summary>
 18/// <typeparam name="T">The type of the items being filtered.</typeparam>
 19/// <typeparam name="TValue">The type of the nullable comparable value (must be a struct implementing IComparable).</typ
 20/// <param name="propertyName">The key that identifies this filter condition.</param>
 21/// <param name="property">The expression representing the nullable comparable property to filter on.</param>
 22/// <param name="comparableOperator">The comparison operator to use (default: EqualsTo).</param>
 23public class NullableComparableFilterViewModel<T, TValue>(
 24    string propertyName,
 25    Expression<Func<T, TValue?>> property,
 26    ComplexComparableOperator comparableOperator = ComplexComparableOperator.EqualsTo)
 027    : FilterConditionViewModel<T>(propertyName)
 28    where TValue : struct, IComparable<TValue>
 29{
 30    /// <summary>
 31    /// Gets the expression representing the nullable comparable property to filter on.
 32    /// </summary>
 033    public Expression<Func<T, TValue?>> Property { get; } = property;
 34
 35    /// <summary>
 36    /// Gets or sets the comparison operator used for matching.
 37    /// </summary>
 038    public ComplexComparableOperator Operator { get; set => SetProperty(ref field, value); } = comparableOperator;
 39
 40    /// <summary>
 41    /// Gets or sets the lower bound value for comparison.
 42    /// </summary>
 43    public TValue? From
 44    {
 45        get;
 046        set => SetProperty(ref field, value);
 47    }
 48
 49    /// <summary>
 50    /// Gets or sets the upper bound value for comparison.
 51    /// </summary>
 52    public TValue? To
 53    {
 54        get;
 055        set => SetProperty(ref field, value);
 56    }
 57
 58    /// <summary>
 59    /// Gets or sets the minimum allowed value for the filter range.
 60    /// </summary>
 61    public TValue? Minimum
 62    {
 63        get;
 064        set => SetProperty(ref field, value);
 65    }
 66
 67    /// <summary>
 68    /// Gets or sets the maximum allowed value for the filter range.
 69    /// </summary>
 70    public TValue? Maximum
 71    {
 72        get;
 073        set => SetProperty(ref field, value);
 74    }
 75
 76    /// <summary>
 77    /// Gets a value indicating whether this filter is in an empty state.
 78    /// </summary>
 079    public override bool IsEmpty => (From is null || From.Equals(default(TValue))) && (To is null || To.Equals(default(T
 80
 81    /// <inheritdoc />
 82    protected override Expression<Func<T, bool>> BuildExpressionCore()
 83    {
 084        var parameter = Property.Parameters[0];
 085        var propertyBody = Property.Body;
 86
 87        // x.Property.HasValue
 088        var hasValue = Expression.Property(propertyBody, nameof(Nullable<>.HasValue));
 89
 90        // x.Property.Value
 091        var propertyValue = Expression.Property(propertyBody, nameof(Nullable<>.Value));
 92
 093        Expression comparison = Operator switch
 094        {
 095            ComplexComparableOperator.EqualsTo when From is not null =>
 096                Expression.Equal(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 097
 098            ComplexComparableOperator.NotEqualsTo when From is not null =>
 099                Expression.NotEqual(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 0100
 0101            ComplexComparableOperator.LessThan when To is not null =>
 0102                Expression.LessThan(propertyValue, Expression.Constant(To.Value, typeof(TValue))),
 0103
 0104            ComplexComparableOperator.GreaterThan when From is not null =>
 0105                Expression.GreaterThan(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 0106
 0107            ComplexComparableOperator.LessEqualThan when To is not null =>
 0108                Expression.LessThanOrEqual(propertyValue, Expression.Constant(To.Value, typeof(TValue))),
 0109
 0110            ComplexComparableOperator.GreaterEqualThan when From is not null =>
 0111                Expression.GreaterThanOrEqual(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 0112
 0113            ComplexComparableOperator.IsBetween when From is not null && To is not null =>
 0114                Expression.AndAlso(
 0115                    Expression.GreaterThanOrEqual(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 0116                    Expression.LessThanOrEqual(propertyValue, Expression.Constant(To.Value, typeof(TValue)))),
 0117
 0118            ComplexComparableOperator.IsNotBetween when From is not null && To is not null =>
 0119                Expression.OrElse(
 0120                    Expression.LessThan(propertyValue, Expression.Constant(From.Value, typeof(TValue))),
 0121                    Expression.GreaterThan(propertyValue, Expression.Constant(To.Value, typeof(TValue)))),
 0122
 0123            _ => Expression.Constant(true)
 0124        };
 125
 126        // Combine: x.Property.HasValue && <comparison>
 0127        var body = Expression.AndAlso(hasValue, comparison);
 128
 0129        return Expression.Lambda<Func<T, bool>>(body, parameter);
 130    }
 131
 132    /// <summary>
 133    /// Resets the filter to its default state by clearing From and To values.
 134    /// </summary>
 135    public override void Reset()
 136    {
 0137        From = null;
 0138        To = null;
 0139    }
 140}
 141