Facet.Mapping.Expressions 3.3.0-alpha.1

This is a prerelease version of Facet.Mapping.Expressions.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Facet.Mapping.Expressions --version 3.3.0-alpha.1
                    
NuGet\Install-Package Facet.Mapping.Expressions -Version 3.3.0-alpha.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Facet.Mapping.Expressions" Version="3.3.0-alpha.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Facet.Mapping.Expressions" Version="3.3.0-alpha.1" />
                    
Directory.Packages.props
<PackageReference Include="Facet.Mapping.Expressions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Facet.Mapping.Expressions --version 3.3.0-alpha.1
                    
#r "nuget: Facet.Mapping.Expressions, 3.3.0-alpha.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Facet.Mapping.Expressions@3.3.0-alpha.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Facet.Mapping.Expressions&version=3.3.0-alpha.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Facet.Mapping.Expressions&version=3.3.0-alpha.1&prerelease
                    
Install as a Cake Tool

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:

  1. Property Mapping: Maps properties between source and target types by name and type compatibility
  2. Parameter Replacement: Replaces lambda parameters with the appropriate target type parameters
  3. Expression Transformation: Recursively transforms all parts of the expression tree
  4. 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 record keyword)
  • Struct-based Facets (using struct keyword)
  • Custom mapping configurations
  • Async mapping scenarios (when combined with Facet.Mapping)
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
5.1.6 19 11/28/2025
5.1.5 25 11/28/2025
5.1.4 55 11/28/2025
5.1.3 67 11/28/2025
5.1.2 104 11/27/2025
5.1.1 101 11/27/2025
5.1.0 102 11/27/2025
5.0.4 135 11/26/2025
5.0.3 138 11/26/2025
5.0.2 144 11/26/2025
5.0.1 153 11/25/2025
5.0.0 154 11/24/2025
5.0.0-alpha5 149 11/24/2025
5.0.0-alpha4 139 11/23/2025
5.0.0-alpha3 152 11/22/2025
5.0.0-alpha2 162 11/22/2025
5.0.0-alpha 251 11/21/2025
4.4.3 290 11/21/2025
4.4.2 320 11/21/2025
4.4.1 382 11/20/2025
4.4.1-alpha4 265 11/16/2025
4.4.1-alpha3 255 11/16/2025
4.4.1-alpha2 260 11/16/2025
4.4.1-alpha 259 11/16/2025
4.4.0 190 11/15/2025
4.4.0-alpha 196 11/14/2025
4.3.3.1 206 11/14/2025
4.3.3 201 11/14/2025
4.3.2.1 202 11/14/2025
4.3.2 261 11/13/2025
4.3.1 265 11/12/2025
4.3.0 108 11/8/2025
4.3.0-alpha 128 11/7/2025
3.4.0 102 11/8/2025
3.3.0 151 11/7/2025
3.3.0-alpha.1 137 11/4/2025
3.3.0-alpha 175 11/3/2025
3.2.2 398 10/29/2025
3.2.1 175 10/27/2025
3.2.1-alpha.1 127 10/27/2025
3.2.1-alpha 164 10/26/2025
3.2.0-alpha 166 10/26/2025
3.1.14 216 10/24/2025
3.1.13 204 10/24/2025
3.1.12 245 10/21/2025
3.1.11 165 10/21/2025
3.1.5 140 10/24/2025
3.1.4 163 10/23/2025
3.1.3 161 10/23/2025
3.1.3-alpha 162 10/22/2025
3.1.2 158 10/21/2025
3.1.2-alpha 156 10/22/2025
3.1.1 169 10/21/2025
3.1.0 171 10/19/2025
3.0.0 117 10/17/2025
2.9.31 216 10/13/2025
2.9.3 174 10/8/2025
2.9.3-alpha 162 10/7/2025
2.9.2 178 10/6/2025
2.9.1 117 10/3/2025
2.9.0 202 10/1/2025
2.8.2 172 10/1/2025
2.8.1 463 9/21/2025
2.8.0 300 9/17/2025
2.7.0 142 9/12/2025
2.6.1 119 9/12/2025
1.0.0 101 11/27/2025