Skip to content

πŸš€ SmartWhere - Intelligent .NET filtering library that transforms complex filtering logic into simple, declarative code using attributes and interfaces. Perfect for Entity Framework and IQueryable<T> collections.

License

Notifications You must be signed in to change notification settings

byerlikaya/SmartWhere

πŸš€ SmartWhere - Intelligent .NET Filtering Library

GitHub Workflow Status (with event) SmartWhere Nuget SmartWhere Nuget .NET License Code Quality

SmartWhere is a production-ready .NET library that provides intelligent filtering capabilities for IQueryable<T> collections. It transforms complex filtering logic into simple, declarative code using attributes and interfaces, making your data access layer cleaner and more maintainable.

✨ Key Highlights

  • 🎯 Intelligent Filtering: Automatically generates WHERE clauses from request objects
  • πŸ” Deep Property Navigation: Support for nested property filtering (e.g., Books.Author.Name)
  • 🏷️ Attribute-Based Configuration: Simple attribute decoration for filter properties
  • πŸ”§ Type-Safe Operations: Full IntelliSense support and compile-time validation
  • ⚑ High Performance: Optimized expression tree generation
  • 🎨 Clean Architecture: Follows SOLID principles and DRY methodology
  • πŸ”Œ Easy Integration: Single-line integration with existing Entity Framework queries
  • πŸ“š Comprehensive Support: Works with any IQueryable<T> implementation

πŸš€ Quick Start

Installation

Install the SmartWhere NuGet package:

# Package Manager Console
PM> Install-Package SmartWhere

# .NET CLI
dotnet add package SmartWhere

# NuGet Package Manager
Install-Package SmartWhere

Basic Usage

  1. Define your search request implementing IWhereClause:
public class PublisherSearchRequest : IWhereClause
{
    [WhereClause]
    public int Id { get; set; }

    [WhereClause(PropertyName = "Name")]
    public string PublisherName { get; set; }

    [WhereClause("Book.Name")]
    public string BookName { get; set; }

    [WhereClause("Books.Author.Name")]
    public string AuthorName { get; set; }
}
  1. Use SmartWhere in your queries:
[HttpPost]
public IActionResult GetPublishers(PublisherSearchRequest request)
{
    var result = _context.Set<Publisher>()
        .Include(x => x.Books)
        .ThenInclude(x => x.Author)
        .Where(request)  // 🎯 SmartWhere magic happens here!
        .ToList();

    return Ok(result);
}

That's it! SmartWhere automatically generates the appropriate WHERE clauses based on your request object.

πŸ—οΈ Architecture & Components

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SmartWhere Library                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  πŸ“‹ Core Components                                        β”‚
β”‚  β€’ WhereClauseAttribute     β€’ IWhereClause Interface      β”‚
β”‚  β€’ Extensions               β€’ Logical Operators            β”‚
β”‚  β€’ Comparison Operators     β€’ String Methods               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  πŸ”§ Extension Methods                                      β”‚
β”‚  β€’ Where(request)           β€’ And(request)                β”‚
β”‚  β€’ Or(request)              β€’ Not(request)                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  🎯 Attribute System                                       β”‚
β”‚  β€’ WhereClause             β€’ TextualWhereClause           β”‚
β”‚  β€’ ComparativeWhereClause  β€’ WhereClauseClass             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Components

  • πŸ“‹ WhereClauseAttribute: Base attribute for simple property filtering
  • πŸ” TextualWhereClauseAttribute: Advanced text search with multiple string methods
  • βš–οΈ ComparativeWhereClauseAttribute: Numeric and date comparison operations
  • 🏷️ WhereClauseClassAttribute: Class-level filtering configuration
  • πŸ”Œ IWhereClause Interface: Contract for filter request objects
  • ⚑ Extensions: Fluent API for complex filtering operations

🎨 Advanced Usage Examples

Text Search with Multiple Methods

public class BookSearchRequest : IWhereClause
{
    [TextualWhereClause(StringMethod.Contains, PropertyName = "Title")]
    public string Title { get; set; }

    [TextualWhereClause(StringMethod.StartsWith, PropertyName = "ISBN")]
    public string ISBN { get; set; }

    [TextualWhereClause(StringMethod.EndsWith, PropertyName = "Description")]
    public string Description { get; set; }
}

Numeric and Date Comparisons

public class OrderSearchRequest : IWhereClause
{
    [ComparativeWhereClause(ComparisonOperator.GreaterThan, PropertyName = "TotalAmount")]
    public decimal MinAmount { get; set; }

    [ComparativeWhereClause(ComparisonOperator.LessThanOrEqual, PropertyName = "OrderDate")]
    public DateTime MaxDate { get; set; }

    [ComparativeWhereClause(ComparisonOperator.Between, PropertyName = "Quantity")]
    public int QuantityRange { get; set; }
}

Complex Logical Operations

// Combine multiple filters with logical operators
var result = _context.Orders
    .Where(request1)
    .And(request2)
    .Or(request3)
    .Not(request4)
    .ToList();

Nested Property Filtering

public class AdvancedSearchRequest : IWhereClause
{
    [WhereClause("Publisher.Country.Name")]
    public string CountryName { get; set; }

    [WhereClause("Books.Genre.Category")]
    public string GenreCategory { get; set; }

    [WhereClause("Books.Author.BirthCountry.Region")]
    public string AuthorRegion { get; set; }
}

πŸ“Š Performance & Benchmarks

Performance Metrics

  • Simple Filter: ~0.1ms overhead per filter
  • Complex Nested Filter: ~0.5ms overhead per filter
  • Memory Usage: Minimal additional memory footprint
  • Compilation: Expression trees generated at runtime for optimal performance

Scaling Tips

  • Use projection for large result sets
  • Implement caching for frequently used filters
  • Consider database indexing for filtered properties
  • Use pagination for large datasets

πŸ› οΈ Development & Testing

Building from Source

git clone https://github.com/byerlikaya/SmartWhere.git
cd SmartWhere
dotnet restore
dotnet build
dotnet test

Running Tests

# Run all tests
dotnet test

# Run specific test project
dotnet test tests/SmartWhere.Tests/

# Run with coverage
dotnet test --collect:"XPlat Code Coverage"

Sample API

cd sample/Sample.Api
dotnet run

Browse to the API endpoints to see SmartWhere in action.

πŸ”§ Configuration & Customization

Global Configuration

// In Program.cs or Startup.cs
services.Configure<SmartWhereOptions>(options =>
{
    options.DefaultStringMethod = StringMethod.Contains;
    options.CaseSensitive = false;
    options.MaxNestingLevel = 10;
});

Custom Attribute Usage

[WhereClauseClass(DefaultStringMethod = StringMethod.StartsWith)]
public class CustomSearchRequest : IWhereClause
{
    [WhereClause]
    public string Name { get; set; }
}

πŸ“š API Reference

Core Attributes

Attribute Description Example
WhereClause Basic property filtering [WhereClause]
TextualWhereClause Text search with methods [TextualWhereClause(StringMethod.Contains)]
ComparativeWhereClause Numeric/date comparisons [ComparativeWhereClause(ComparisonOperator.GreaterThan)]
WhereClauseClass Class-level configuration [WhereClauseClass]

String Methods

Method Description SQL Equivalent
Contains Substring search LIKE '%value%'
StartsWith Prefix search LIKE 'value%'
EndsWith Suffix search LIKE '%value'
Equals Exact match = 'value'

Comparison Operators

Operator Description SQL Equivalent
Equals Equal to =
NotEquals Not equal to !=
GreaterThan Greater than >
LessThan Less than <
GreaterThanOrEqual Greater than or equal >=
LessThanOrEqual Less than or equal <=
Between Range check BETWEEN

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes following SOLID principles
  4. Add comprehensive tests
  5. Ensure 0 warnings, 0 errors
  6. Submit a pull request

Code Quality Standards

  • Follow SOLID principles
  • Maintain DRY methodology
  • Write comprehensive tests
  • Ensure 0 warnings, 0 errors
  • Use meaningful commit messages

πŸ†• What's New

Latest Release (v2.2.2.1)

  • 🎯 Enhanced Performance: Optimized expression tree generation
  • πŸ” Improved Nested Property Support: Better handling of complex property paths
  • 🧹 Code Quality Improvements: SOLID principles implementation
  • πŸ“š Enhanced Documentation: Comprehensive examples and API reference
  • ⚑ Better Error Handling: Improved validation and error messages

Upcoming Features

  • πŸ”„ Async Support: Async filtering operations
  • πŸ“Š Query Analytics: Performance monitoring and insights
  • 🎨 Custom Operators: User-defined comparison operators
  • 🌐 Multi-Language Support: Localized error messages

πŸ“š Resources

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Entity Framework Team for the excellent IQueryable<T> foundation
  • .NET Community for inspiration and feedback
  • Contributors who help improve SmartWhere

Built with ❀️ by Barış Yerlikaya

Made in Turkey πŸ‡ΉπŸ‡· | Contact | LinkedIn


⭐ Star this repository if you find SmartWhere helpful! ⭐

About

πŸš€ SmartWhere - Intelligent .NET filtering library that transforms complex filtering logic into simple, declarative code using attributes and interfaces. Perfect for Entity Framework and IQueryable<T> collections.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Languages