Polish 7 (#3381)
This commit is contained in:
parent
cb810a2d8f
commit
3e3b6ba92b
26 changed files with 1631 additions and 212 deletions
|
@ -14,6 +14,7 @@ namespace API.Extensions.QueryExtensions.Filtering;
|
|||
public static class SeriesFilter
|
||||
{
|
||||
private const float FloatingPointTolerance = 0.001f;
|
||||
|
||||
public static IQueryable<Series> HasLanguage(this IQueryable<Series> queryable, bool condition,
|
||||
FilterComparison comparison, IList<string> languages)
|
||||
{
|
||||
|
@ -255,7 +256,8 @@ public static class SeriesFilter
|
|||
.Where(s => s.Progress != null)
|
||||
.Select(s => new
|
||||
{
|
||||
Series = s,
|
||||
SeriesId = s.Id,
|
||||
SeriesName = s.Name,
|
||||
Percentage = s.Progress
|
||||
.Where(p => p != null && p.AppUserId == userId)
|
||||
.Sum(p => p != null ? (p.PagesRead * 1.0f / s.Pages) : 0f) * 100f
|
||||
|
@ -298,7 +300,7 @@ public static class SeriesFilter
|
|||
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
|
||||
}
|
||||
|
||||
var ids = subQuery.Select(s => s.Series.Id).ToList();
|
||||
var ids = subQuery.Select(s => s.SeriesId);
|
||||
return queryable.Where(s => ids.Contains(s.Id));
|
||||
}
|
||||
|
||||
|
@ -312,7 +314,8 @@ public static class SeriesFilter
|
|||
.Include(s => s.ExternalSeriesMetadata)
|
||||
.Select(s => new
|
||||
{
|
||||
Series = s,
|
||||
SeriesId = s.Id,
|
||||
SeriesName = s.Name,
|
||||
AverageRating = s.ExternalSeriesMetadata.AverageExternalRating
|
||||
})
|
||||
.AsSplitQuery()
|
||||
|
@ -354,7 +357,7 @@ public static class SeriesFilter
|
|||
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
|
||||
}
|
||||
|
||||
var ids = subQuery.Select(s => s.Series.Id).ToList();
|
||||
var ids = subQuery.Select(s => s.SeriesId);
|
||||
return queryable.Where(s => ids.Contains(s.Id));
|
||||
}
|
||||
|
||||
|
@ -372,7 +375,8 @@ public static class SeriesFilter
|
|||
.Where(s => s.Progress != null)
|
||||
.Select(s => new
|
||||
{
|
||||
Series = s,
|
||||
SeriesId = s.Id,
|
||||
SeriesName = s.Name,
|
||||
MaxDate = s.Progress.Where(p => p != null && p.AppUserId == userId)
|
||||
.Select(p => (DateTime?) p.LastModified)
|
||||
.DefaultIfEmpty()
|
||||
|
@ -420,7 +424,7 @@ public static class SeriesFilter
|
|||
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
|
||||
}
|
||||
|
||||
var ids = subQuery.Select(s => s.Series.Id).ToList();
|
||||
var ids = subQuery.Select(s => s.SeriesId);
|
||||
return queryable.Where(s => ids.Contains(s.Id));
|
||||
}
|
||||
|
||||
|
@ -434,7 +438,8 @@ public static class SeriesFilter
|
|||
.Where(s => s.Progress != null)
|
||||
.Select(s => new
|
||||
{
|
||||
Series = s,
|
||||
SeriesId = s.Id,
|
||||
SeriesName = s.Name,
|
||||
MaxDate = s.Progress.Where(p => p != null && p.AppUserId == userId)
|
||||
.Select(p => (DateTime?) p.LastModified)
|
||||
.DefaultIfEmpty()
|
||||
|
@ -480,7 +485,7 @@ public static class SeriesFilter
|
|||
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
|
||||
}
|
||||
|
||||
var ids = subQuery.Select(s => s.Series.Id).ToList();
|
||||
var ids = subQuery.Select(s => s.SeriesId);
|
||||
return queryable.Where(s => ids.Contains(s.Id));
|
||||
}
|
||||
|
||||
|
|
|
@ -113,109 +113,55 @@ public static class QueryableExtensions
|
|||
return condition ? queryable.Where(predicate) : queryable;
|
||||
}
|
||||
|
||||
public static IQueryable<T> WhereLike<T>(this IQueryable<T> queryable, bool condition, Expression<Func<T, string>> propertySelector, string searchQuery)
|
||||
where T : class
|
||||
{
|
||||
if (!condition || string.IsNullOrEmpty(searchQuery)) return queryable;
|
||||
|
||||
var method = typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string) });
|
||||
var dbFunctions = typeof(EF).GetMethod(nameof(EF.Functions))?.Invoke(null, null);
|
||||
var searchExpression = Expression.Constant($"%{searchQuery}%");
|
||||
var likeExpression = Expression.Call(method, Expression.Constant(dbFunctions), propertySelector.Body, searchExpression);
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(likeExpression, propertySelector.Parameters[0]);
|
||||
|
||||
return queryable.Where(lambda);
|
||||
}
|
||||
|
||||
public static IQueryable<T> WhereGreaterThan<T>(this IQueryable<T> source,
|
||||
Expression<Func<T, float>> selector,
|
||||
float value,
|
||||
float tolerance = DefaultTolerance)
|
||||
float value)
|
||||
{
|
||||
var parameter = selector.Parameters[0];
|
||||
var propertyAccess = selector.Body;
|
||||
|
||||
// Absolute difference comparison: (propertyAccess - value) > tolerance
|
||||
var difference = Expression.Subtract(propertyAccess, Expression.Constant(value));
|
||||
var absoluteDifference = Expression.Condition(
|
||||
Expression.LessThan(difference, Expression.Constant(0f)),
|
||||
Expression.Negate(difference),
|
||||
difference);
|
||||
|
||||
var greaterThanExpression = Expression.GreaterThan(propertyAccess, Expression.Constant(value));
|
||||
var toleranceExpression = Expression.GreaterThan(absoluteDifference, Expression.Constant(tolerance));
|
||||
var combinedExpression = Expression.AndAlso(greaterThanExpression, toleranceExpression);
|
||||
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(combinedExpression, parameter);
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(greaterThanExpression, parameter);
|
||||
|
||||
return source.Where(lambda);
|
||||
}
|
||||
|
||||
public static IQueryable<T> WhereGreaterThanOrEqual<T>(this IQueryable<T> source,
|
||||
Expression<Func<T, float>> selector,
|
||||
float value,
|
||||
float tolerance = DefaultTolerance)
|
||||
float value)
|
||||
{
|
||||
var parameter = selector.Parameters[0];
|
||||
var propertyAccess = selector.Body;
|
||||
|
||||
var difference = Expression.Subtract(propertyAccess, Expression.Constant(value));
|
||||
var absoluteDifference = Expression.Condition(
|
||||
Expression.LessThan(difference, Expression.Constant(0f)),
|
||||
Expression.Negate(difference),
|
||||
difference);
|
||||
|
||||
var greaterThanOrEqualExpression = Expression.GreaterThanOrEqual(propertyAccess, Expression.Constant(value));
|
||||
var toleranceExpression = Expression.GreaterThanOrEqual(absoluteDifference, Expression.Constant(tolerance));
|
||||
var combinedExpression = Expression.AndAlso(greaterThanOrEqualExpression, toleranceExpression);
|
||||
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(combinedExpression, parameter);
|
||||
var greaterThanExpression = Expression.GreaterThanOrEqual(propertyAccess, Expression.Constant(value));
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(greaterThanExpression, parameter);
|
||||
|
||||
return source.Where(lambda);
|
||||
}
|
||||
|
||||
public static IQueryable<T> WhereLessThan<T>(this IQueryable<T> source,
|
||||
Expression<Func<T, float>> selector,
|
||||
float value,
|
||||
float tolerance = DefaultTolerance)
|
||||
float value)
|
||||
{
|
||||
var parameter = selector.Parameters[0];
|
||||
var propertyAccess = selector.Body;
|
||||
|
||||
var difference = Expression.Subtract(propertyAccess, Expression.Constant(value));
|
||||
var absoluteDifference = Expression.Condition(
|
||||
Expression.LessThan(difference, Expression.Constant(0f)),
|
||||
Expression.Negate(difference),
|
||||
difference);
|
||||
|
||||
var lessThanExpression = Expression.LessThan(propertyAccess, Expression.Constant(value));
|
||||
var toleranceExpression = Expression.LessThan(absoluteDifference, Expression.Constant(tolerance));
|
||||
var combinedExpression = Expression.AndAlso(lessThanExpression, toleranceExpression);
|
||||
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(combinedExpression, parameter);
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(lessThanExpression, parameter);
|
||||
|
||||
return source.Where(lambda);
|
||||
}
|
||||
|
||||
public static IQueryable<T> WhereLessThanOrEqual<T>(this IQueryable<T> source,
|
||||
Expression<Func<T, float>> selector,
|
||||
float value,
|
||||
float tolerance = DefaultTolerance)
|
||||
float value)
|
||||
{
|
||||
var parameter = selector.Parameters[0];
|
||||
var propertyAccess = selector.Body;
|
||||
|
||||
var difference = Expression.Subtract(propertyAccess, Expression.Constant(value));
|
||||
var absoluteDifference = Expression.Condition(
|
||||
Expression.LessThan(difference, Expression.Constant(0f)),
|
||||
Expression.Negate(difference),
|
||||
difference);
|
||||
|
||||
var lessThanOrEqualExpression = Expression.LessThanOrEqual(propertyAccess, Expression.Constant(value));
|
||||
var toleranceExpression = Expression.LessThanOrEqual(absoluteDifference, Expression.Constant(tolerance));
|
||||
var combinedExpression = Expression.AndAlso(lessThanOrEqualExpression, toleranceExpression);
|
||||
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(combinedExpression, parameter);
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(lessThanOrEqualExpression, parameter);
|
||||
|
||||
return source.Where(lambda);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue