Skip to content
4 changes: 2 additions & 2 deletions src/QueryBuilder/ExpandBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace DataverseQuery
namespace DataverseQuery.QueryBuilder
{
public sealed class ExpandBuilder
{
Expand All @@ -18,4 +18,4 @@ public ExpandBuilder(string relationshipName, Type targetType, IQueryBuilder bui
IsCollection = isCollection;
}
}
}
}
167 changes: 167 additions & 0 deletions src/QueryBuilder/Extensions/WhereGroupBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using System.Linq.Expressions;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace DataverseQuery.QueryBuilder.Extensions
{
/// <summary>
/// Extension methods for WhereGroupBuilder to provide common filter patterns.
/// </summary>
public static class WhereGroupBuilderExtensions
{
/// <summary>
/// Adds an equality condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="value">The value to compare against.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereEqual<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector,
TValue value)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.Equal, value);
}

/// <summary>
/// Adds a 'like' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="pattern">The pattern to match (supports % wildcards).</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereLike<TEntity>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, string>> fieldSelector,
string pattern)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.Like, pattern);
}

/// <summary>
/// Adds an 'in' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="values">The values to check against.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereIn<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector,
params TValue[] values)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.In, values);
}

/// <summary>
/// Adds a 'not equal' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="value">The value to compare against.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereNotEqual<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector,
TValue value)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.NotEqual, value);
}

/// <summary>
/// Adds a 'greater than' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="value">The value to compare against.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereGreaterThan<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector,
TValue value)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.GreaterThan, value);
}

/// <summary>
/// Adds a 'less than' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <param name="value">The value to compare against.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereLessThan<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector,
TValue value)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.LessThan, value);
}

/// <summary>
/// Adds a 'null' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereNull<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.Null);
}

/// <summary>
/// Adds a 'not null' condition.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="builder">The WhereGroupBuilder instance.</param>
/// <param name="fieldSelector">The lambda expression selecting the field.</param>
/// <returns>This WhereGroupBuilder instance for method chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when builder or fieldSelector is null.</exception>
public static WhereGroupBuilder<TEntity> WhereNotNull<TEntity, TValue>(
this WhereGroupBuilder<TEntity> builder,
Expression<Func<TEntity, TValue>> fieldSelector)
where TEntity : Entity
{
ArgumentNullException.ThrowIfNull(builder);
return builder.Where(fieldSelector, ConditionOperator.NotNull);
}
}
}
2 changes: 1 addition & 1 deletion src/QueryBuilder/IQueryBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.Xrm.Sdk.Query;

namespace DataverseQuery
namespace DataverseQuery.QueryBuilder
{
public interface IQueryBuilder
{
Expand Down
21 changes: 21 additions & 0 deletions src/QueryBuilder/Interfaces/IAttributeNameResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Linq.Expressions;
using Microsoft.Xrm.Sdk;

namespace DataverseQuery.QueryBuilder.Interfaces
{
/// <summary>
/// Resolves attribute names from lambda expressions.
/// </summary>
public interface IAttributeNameResolver
{
/// <summary>
/// Gets the attribute name from a property selector expression.
/// </summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TValue">The value type of the property.</typeparam>
/// <param name="fieldSelector">The lambda expression selecting the property.</param>
/// <returns>The attribute name, or null if it cannot be resolved.</returns>
string? GetAttributeName<TEntity, TValue>(Expression<Func<TEntity, TValue>> fieldSelector)
where TEntity : Entity;
}
}
16 changes: 16 additions & 0 deletions src/QueryBuilder/Interfaces/IValueConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace DataverseQuery.QueryBuilder.Interfaces
{
/// <summary>
/// Converts values for use in Dataverse queries.
/// </summary>
public interface IValueConverter
{
/// <summary>
/// Converts an array of values to their primitive representations for use in Dataverse queries.
/// </summary>
/// <typeparam name="TValue">The type of values to convert.</typeparam>
/// <param name="values">The values to convert.</param>
/// <returns>An array of converted values suitable for Dataverse queries.</returns>
object[] ConvertValues<TValue>(TValue[] values);
}
}
Loading