Facet.Mapping.Expressions
3.1.14
dotnet add package Facet.Mapping.Expressions --version 3.1.14
NuGet\Install-Package Facet.Mapping.Expressions -Version 3.1.14
<PackageReference Include="Facet.Mapping.Expressions" Version="3.1.14" />
<PackageVersion Include="Facet.Mapping.Expressions" Version="3.1.14" />
<PackageReference Include="Facet.Mapping.Expressions" />
paket add Facet.Mapping.Expressions --version 3.1.14
#r "nuget: Facet.Mapping.Expressions, 3.1.14"
#:package Facet.Mapping.Expressions@3.1.14
#addin nuget:?package=Facet.Mapping.Expressions&version=3.1.14
#tool nuget:?package=Facet.Mapping.Expressions&version=3.1.14
Facet.Mapping.Expressions
Expression tree transformation and mapping utilities for Facet DTOs. Transform predicates, selectors, and other expressions between source entities and their Facet projections.
Features
- Predicate Mapping: Transform filter expressions from entity types to DTO types
- Selector Mapping: Transform sorting and selection expressions
- Generic Expression Transformation: Handle any lambda expression pattern
- Expression Composition: Combine predicates with AND/OR logic, negation
- Performance Optimized: Caches reflection results and property mappings
- Type Safe: Compile-time checking with full IntelliSense support
Installation
dotnet add package Facet.Mapping.Expressions
Quick Start
Basic Predicate Mapping
Transform business logic from entities to DTOs:
using Facet.Mapping.Expressions;
// Original predicate for entity
Expression<Func<User, bool>> entityFilter = u => u.IsActive && u.Age > 18;
// Transform to work with DTO
Expression<Func<UserDto, bool>> dtoFilter = entityFilter.MapToFacet<UserDto>();
// Use with LINQ queries
var results = dtoCollection.Where(dtoFilter.Compile()).ToList();
Selector Expression Mapping
Transform sorting and selection logic:
// Original selector for entity
Expression<Func<User, string>> entitySelector = u => u.LastName;
// Transform to work with DTO
Expression<Func<UserDto, string>> dtoSelector = entitySelector.MapToFacet<UserDto, string>();
// Use for sorting
var sorted = dtoCollection.OrderBy(dtoSelector.Compile()).ToList();
Expression Composition
Combine multiple conditions:
var isAdult = (Expression<Func<User, bool>>)(u => u.Age >= 18);
var isActive = (Expression<Func<User, bool>>)(u => u.IsActive);
var isVip = (Expression<Func<User, bool>>)(u => u.IsVip);
// Combine with AND
var adultAndActive = FacetExpressionExtensions.CombineWithAnd(isAdult, isActive);
// Combine with OR
var vipOrAdult = FacetExpressionExtensions.CombineWithOr(isVip, isAdult);
// Negate a condition
var inactive = isActive.Negate();
// Transform composed expressions to DTOs
var dtoFilter = adultAndActive.MapToFacet<UserDto>();
Advanced Usage
Generic Expression Transformation
Handle complex expressions with anonymous objects, method calls, etc.:
// Complex expression with method calls and projections
Expression<Func<User, object>> complexExpr = u => new {
FullName = u.FirstName + " " + u.LastName,
IsEligible = u.Age > 21 && u.Email.Contains("@company.com"),
DisplayAge = u.Age.ToString()
};
// Transform to DTO context
var dtoExpr = complexExpr.MapToFacetGeneric<UserDto>();
Working with Repository Patterns
Common pattern for reusable business logic:
public class UserRepository
{
private readonly Expression<Func<User, bool>> _activeUsersFilter =
u => u.IsActive && !u.IsDeleted;
public IQueryable<User> GetActiveUsers(IQueryable<User> query)
{
return query.Where(_activeUsersFilter);
}
public IEnumerable<UserDto> GetActiveUserDtos(IEnumerable<UserDto> dtos)
{
var dtoFilter = _activeUsersFilter.MapToFacet<UserDto>();
return dtos.Where(dtoFilter.Compile());
}
}
Dynamic Query Building
Build complex queries dynamically:
public static class UserFilters
{
public static Expression<Func<User, bool>> ByAgeRange(int minAge, int maxAge) =>
u => u.Age >= minAge && u.Age <= maxAge;
public static Expression<Func<User, bool>> ByStatus(bool isActive) =>
u => u.IsActive == isActive;
public static Expression<Func<User, bool>> ByEmailDomain(string domain) =>
u => u.Email.EndsWith("@" + domain);
}
// Combine filters dynamically
var filters = new List<Expression<Func<User, bool>>>();
if (ageFilter.HasValue)
filters.Add(UserFilters.ByAgeRange(ageFilter.Value.Min, ageFilter.Value.Max));
if (activeOnly)
filters.Add(UserFilters.ByStatus(true));
if (!string.IsNullOrEmpty(emailDomain))
filters.Add(UserFilters.ByEmailDomain(emailDomain));
// Combine all filters
var combinedFilter = FacetExpressionExtensions.CombineWithAnd(filters.ToArray());
// Apply to both entities and DTOs
var entityResults = entityQuery.Where(combinedFilter);
var dtoFilter = combinedFilter.MapToFacet<UserDto>();
var dtoResults = dtoCollection.Where(dtoFilter.Compile());
How It Works
The library uses expression tree visitors to transform expressions from source types to target (Facet) types:
- Property Mapping: Maps properties between source and target types by name and type compatibility
- Parameter Replacement: Replaces lambda parameters with the appropriate target type parameters
- Expression Transformation: Recursively transforms all parts of the expression tree
- Type Safety: Maintains compile-time type checking throughout the transformation
Supported Expression Types
- Binary expressions: Comparisons (
==,!=,>,<, etc.), logical operations (&&,||) - Unary expressions: Negation (
!), conversions - Member access: Property and field access (
u.Name,u.Age) - Method calls: Instance and static method calls (with compatible signatures)
- Constants and literals: Preserved as-is
- Complex projections: Anonymous objects, new expressions
Performance Considerations
- Property mappings are cached per type pair
- Reflection results are cached for better performance
- Expression compilation is lazy - only when needed
- Thread-safe caching mechanisms
Integration with Facet
This library works seamlessly with all Facet-generated types:
- Standard Facets with
[Facet]attribute - Record-based Facets (using
recordkeyword) - Struct-based Facets (using
structkeyword) - Custom mapping configurations
- Async mapping scenarios (when combined with
Facet.Mapping)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Facet.Extensions (>= 3.1.14)
- Facet.Mapping (>= 3.1.14)
- System.Collections.Immutable (>= 9.0.10)
-
net9.0
- Facet.Extensions (>= 3.1.14)
- Facet.Mapping (>= 3.1.14)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.1.14 | 0 | 10/24/2025 |
| 3.1.13 | 0 | 10/24/2025 |
| 3.1.12 | 117 | 10/21/2025 |
| 3.1.11 | 70 | 10/21/2025 |
| 3.1.5 | 0 | 10/24/2025 |
| 3.1.4 | 31 | 10/23/2025 |
| 3.1.3 | 53 | 10/23/2025 |
| 3.1.3-alpha | 68 | 10/22/2025 |
| 3.1.2 | 65 | 10/21/2025 |
| 3.1.2-alpha | 63 | 10/22/2025 |
| 3.1.1 | 73 | 10/21/2025 |
| 3.1.0 | 80 | 10/19/2025 |
| 3.0.0 | 103 | 10/17/2025 |
| 2.9.31 | 183 | 10/13/2025 |
| 2.9.3 | 163 | 10/8/2025 |
| 2.9.3-alpha | 153 | 10/7/2025 |
| 2.9.2 | 166 | 10/6/2025 |
| 2.9.1 | 107 | 10/3/2025 |
| 2.9.0 | 187 | 10/1/2025 |
| 2.8.2 | 164 | 10/1/2025 |
| 2.8.1 | 343 | 9/21/2025 |
| 2.8.0 | 295 | 9/17/2025 |
| 2.7.0 | 136 | 9/12/2025 |
| 2.6.1 | 111 | 9/12/2025 |