C
C#2mo ago
HeavenVR

Is there a better way to write this QueryBuilder?

Its my first time writing one and i want to make sure im doing it right
public static class IQueryableExtensions
{
private static Expression<Func<TEntity, bool>> EntityPropExpr<TEntity>(Expression navigationSelector, Func<InvocationExpression, BinaryExpression> binaryExpressionGetter)
{
// Create a parameter for TEntity (entity)
var entityParameter = Expression.Parameter(typeof(TEntity), "entity");

// Access the prop from the navigation selector
var entityExpression = Expression.Invoke(navigationSelector, entityParameter);

var binaryExpression = binaryExpressionGetter(entityExpression);

// Build the lambda expression
return Expression.Lambda<Func<TEntity, bool>>(binaryExpression, entityParameter);
}

private static BinaryExpression UserIdMatchesExpr(InvocationExpression userExpression, Guid userId)
{
return Expression.Equal(
Expression.Property(userExpression, nameof(OpenShockDb.User.Id)),
Expression.Constant(userId)
);
}

private static Expression<Func<TEntity, bool>> IsUserMatchExpr<TEntity>(Expression navigationSelector, Guid userId)
{
return EntityPropExpr<TEntity>(navigationSelector, user => UserIdMatchesExpr(user, userId));
}

public static IQueryable<TEntity> WhereIsUser<TEntity>(this IQueryable<TEntity> source, Expression navigationSelector, Guid userId)
{
return source.Where(IsUserMatchExpr<TEntity>(navigationSelector, userId));
}
}
public static class IQueryableExtensions
{
private static Expression<Func<TEntity, bool>> EntityPropExpr<TEntity>(Expression navigationSelector, Func<InvocationExpression, BinaryExpression> binaryExpressionGetter)
{
// Create a parameter for TEntity (entity)
var entityParameter = Expression.Parameter(typeof(TEntity), "entity");

// Access the prop from the navigation selector
var entityExpression = Expression.Invoke(navigationSelector, entityParameter);

var binaryExpression = binaryExpressionGetter(entityExpression);

// Build the lambda expression
return Expression.Lambda<Func<TEntity, bool>>(binaryExpression, entityParameter);
}

private static BinaryExpression UserIdMatchesExpr(InvocationExpression userExpression, Guid userId)
{
return Expression.Equal(
Expression.Property(userExpression, nameof(OpenShockDb.User.Id)),
Expression.Constant(userId)
);
}

private static Expression<Func<TEntity, bool>> IsUserMatchExpr<TEntity>(Expression navigationSelector, Guid userId)
{
return EntityPropExpr<TEntity>(navigationSelector, user => UserIdMatchesExpr(user, userId));
}

public static IQueryable<TEntity> WhereIsUser<TEntity>(this IQueryable<TEntity> source, Expression navigationSelector, Guid userId)
{
return source.Where(IsUserMatchExpr<TEntity>(navigationSelector, userId));
}
}
3 Replies
Anton
Anton2mo ago
Yes, I find making a "template" expression, and then replacing the parameter in its body with another expression to be less error prone I can share a utility with you a bit later $code
MODiX
MODiX2mo ago
To post C# code type the following: ```cs // code here ``` Get an example by typing $codegif in chat For longer snippets, use: https://paste.mod.gg/
Anton
Anton2mo ago
BlazeBin - iusgtzbpsloo
A tool for sharing your source code with the world!
Want results from more Discord servers?
Add your server