Welcome to SmartWhere! This guide will help you get started with the library quickly and efficiently.
Install the SmartWhere NuGet package using one of these methods:
# Package Manager Console
PM> Install-Package SmartWhere
# .NET CLI
dotnet add package SmartWhere
# NuGet Package Manager
Install-Package SmartWhere
Add this to your .csproj
file:
<PackageReference Include="SmartWhere" Version="2.2.3" />
Add the following using statement to your files:
using SmartWhere;
Create a class that implements IWhereClause
:
public class BookSearchRequest : IWhereClause
{
[WhereClause]
public string Title { get; set; }
[WhereClause]
public string Author { get; set; }
[WhereClause]
public int? PublishedYear { get; set; }
}
[HttpPost]
public IActionResult SearchBooks(BookSearchRequest request)
{
var result = _context.Books
.Where(request) // π― SmartWhere magic happens here!
.ToList();
return Ok(result);
}
Hereβs a complete working example:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int PublishedYear { get; set; }
public decimal Price { get; set; }
public string Genre { get; set; }
}
public class Publisher
{
public int Id { get; set; }
public string Name { get; set; }
public List<Book> Books { get; set; } = new();
}
public class AdvancedBookSearchRequest : IWhereClause
{
[WhereClause]
public string Title { get; set; }
[WhereClause("Author")]
public string AuthorName { get; set; }
[WhereClause("PublishedYear")]
public int? Year { get; set; }
[WhereClause("Publisher.Name")]
public string PublisherName { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly ApplicationDbContext _context;
public BooksController(ApplicationDbContext context)
{
_context = context;
}
[HttpPost("search")]
public async Task<IActionResult> SearchBooks(AdvancedBookSearchRequest request)
{
var books = await _context.Books
.Include(b => b.Publisher)
.Where(request)
.ToListAsync();
return Ok(books);
}
}
All search request classes must implement this interface:
public interface IWhereClause
{
// No methods required - it's a marker interface
}
The basic attribute for simple property filtering:
[WhereClause] // Same property name
[WhereClause("PropertyName")] // Different property name
[WhereClause(PropertyName = "PropertyName")] // Explicit property name
SmartWhere automatically maps properties between your request object and entity properties:
// Request property: AuthorName
// Entity property: Author
[WhereClause("Author")]
public string AuthorName { get; set; }
public class TextSearchRequest : IWhereClause
{
[TextualWhereClause(StringMethod.Contains)]
public string Title { get; set; }
[TextualWhereClause(StringMethod.StartsWith)]
public string Author { get; set; }
}
public class NumericSearchRequest : IWhereClause
{
[ComparativeWhereClause(ComparisonOperator.GreaterThan)]
public int? MinYear { get; set; }
[ComparativeWhereClause(ComparisonOperator.LessThan)]
public decimal? MaxPrice { get; set; }
}
public class LogicalSearchRequest : IWhereClause
{
[WhereClause(LogicalOperator.OR)]
public string Title { get; set; }
[WhereClause(LogicalOperator.OR)]
public string Author { get; set; }
}
β Wrong:
public class SearchRequest // Missing IWhereClause
{
[WhereClause]
public string Name { get; set; }
}
β Correct:
public class SearchRequest : IWhereClause
{
[WhereClause]
public string Name { get; set; }
}
β Wrong:
[WhereClause("NonExistentProperty")]
public string Name { get; set; }
β Correct:
[WhereClause("Name")] // Property exists in entity
public string Name { get; set; }
β Wrong:
var result = _context.Books
.Where(request) // Will fail for nested properties
.ToList();
β Correct:
var result = _context.Books
.Include(b => b.Author)
.Include(b => b.Publisher)
.Where(request)
.ToList();
Last Updated: 2025-01-16
Version: 2.2.3