Facet.Mapping.Expressions 4.3.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Facet.Mapping.Expressions --version 4.3.2
                    
NuGet\Install-Package Facet.Mapping.Expressions -Version 4.3.2
                    
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="4.3.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Facet.Mapping.Expressions" Version="4.3.2" />
                    
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 4.3.2
                    
#r "nuget: Facet.Mapping.Expressions, 4.3.2"
                    
#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@4.3.2
                    
#: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=4.3.2
                    
Install as a Cake Addin
#tool nuget:?package=Facet.Mapping.Expressions&version=4.3.2
                    
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.0.1 17 11/25/2025
5.0.0 39 11/24/2025
5.0.0-alpha5 35 11/24/2025
5.0.0-alpha4 44 11/23/2025
5.0.0-alpha3 81 11/22/2025
5.0.0-alpha2 114 11/22/2025
5.0.0-alpha 203 11/21/2025
4.4.3 240 11/21/2025
4.4.2 272 11/21/2025
4.4.1 345 11/20/2025
4.4.1-alpha4 263 11/16/2025
4.4.1-alpha3 253 11/16/2025
4.4.1-alpha2 258 11/16/2025
4.4.1-alpha 257 11/16/2025
4.4.0 177 11/15/2025
4.4.0-alpha 194 11/14/2025
4.3.3.1 202 11/14/2025
4.3.3 197 11/14/2025
4.3.2.1 198 11/14/2025
4.3.2 257 11/13/2025
4.3.1 262 11/12/2025
4.3.0 105 11/8/2025
4.3.0-alpha 126 11/7/2025
3.4.0 98 11/8/2025
3.3.0 148 11/7/2025
3.3.0-alpha.1 135 11/4/2025
3.3.0-alpha 174 11/3/2025
3.2.2 388 10/29/2025
3.2.1 171 10/27/2025
3.2.1-alpha.1 127 10/27/2025
3.2.1-alpha 163 10/26/2025
3.2.0-alpha 165 10/26/2025
3.1.14 213 10/24/2025
3.1.13 202 10/24/2025
3.1.12 244 10/21/2025
3.1.11 164 10/21/2025
3.1.5 139 10/24/2025
3.1.4 161 10/23/2025
3.1.3 160 10/23/2025
3.1.3-alpha 161 10/22/2025
3.1.2 156 10/21/2025
3.1.2-alpha 155 10/22/2025
3.1.1 168 10/21/2025
3.1.0 169 10/19/2025
3.0.0 113 10/17/2025
2.9.31 214 10/13/2025
2.9.3 172 10/8/2025
2.9.3-alpha 161 10/7/2025
2.9.2 177 10/6/2025
2.9.1 116 10/3/2025
2.9.0 201 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 141 9/12/2025
2.6.1 119 9/12/2025