-
-
Notifications
You must be signed in to change notification settings - Fork 51
17_MapWhen
github-actions[bot] edited this page Dec 18, 2025
·
1 revision
The [MapWhen] attribute enables conditional property mapping based on source property values. Properties are only mapped when the specified condition evaluates to true.
[Facet(typeof(Order))]
public partial class OrderDto
{
[MapWhen("Status == OrderStatus.Completed")]
public DateTime? CompletedAt { get; set; }
}When Status is Completed, CompletedAt is mapped from source. Otherwise, it defaults to null.
[MapWhen("IsActive")]
public string? Email { get; set; }[MapWhen("Status == OrderStatus.Completed")]
public DateTime? CompletedAt { get; set; }
[MapWhen("Status != OrderStatus.Cancelled")]
public string? TrackingNumber { get; set; }[MapWhen("Email != null")]
public string? Email { get; set; }[MapWhen("Age >= 18")]
public string? AdultContent { get; set; }[MapWhen("!IsDeleted")]
public string? Content { get; set; }Multiple [MapWhen] attributes on the same property are combined with AND logic:
[MapWhen("IsActive")]
[MapWhen("Status == OrderStatus.Completed")]
public DateTime? CompletedAt { get; set; }This maps CompletedAt only when IsActive is true AND Status is Completed.
// Input
[Facet(typeof(Order))]
public partial class OrderDto
{
[MapWhen("Status == OrderStatus.Completed")]
public DateTime? CompletedAt { get; set; }
}
// Generated constructor
public OrderDto(Order source)
{
Id = source.Id;
Status = source.Status;
CompletedAt = (source.Status == OrderStatus.Completed)
? source.CompletedAt
: default;
}The same conditional logic is applied in the Projection expression for use with Entity Framework Core:
public static Expression<Func<Order, OrderDto>> Projection => source => new OrderDto
{
Id = source.Id,
Status = source.Status,
CompletedAt = (source.Status == OrderStatus.Completed)
? source.CompletedAt
: default
};| Property | Type | Description |
|---|---|---|
Condition |
string |
The condition expression (required) |
Default |
object? |
Custom default value when condition is false |
IncludeInProjection |
bool |
Whether to include in Projection expression (default: true) |
[MapWhen("HasPrice", Default = 0)]
public decimal Price { get; set; }For conditions that can't be translated to SQL:
[MapWhen("IsActive", IncludeInProjection = false)]
public string? Email { get; set; }The condition string uses C# expression syntax:
- Comparison:
==,!=,<,>,<=,>= - Logical:
&&,||,!
- Simple:
IsActive,Status,Email - Enum values:
OrderStatus.Completed,Status == OrderStatus.Pending
- Booleans:
true,false - Null:
null - Numbers:
18,0
[Facet(typeof(Subscription))]
public partial class SubscriptionDto
{
public SubscriptionStatus Status { get; set; }
[MapWhen("Status == SubscriptionStatus.Active")]
public DateTime? NextBillingDate { get; set; }
[MapWhen("Status == SubscriptionStatus.Cancelled")]
public string? CancellationReason { get; set; }
}[Facet(typeof(Employee))]
public partial class EmployeeDto
{
public string Name { get; set; }
[MapWhen("!IsSalaryConfidential")]
public decimal? Salary { get; set; }
}[Facet(typeof(User))]
public partial class UserDto
{
public int Age { get; set; }
[MapWhen("Age >= 18")]
public string? AdultPreferences { get; set; }
}- Method calls in conditions (like
string.IsNullOrEmpty()) are not supported - Nested property access (like
Address.City) is not supported - Complex expressions may need to be simplified
- Keep conditions simple - Use basic comparisons and boolean checks
- Use nullable properties - Since conditions may be false, properties should typically be nullable
- Consider EF Core translation - If using projections with a database, ensure conditions can translate to SQL
- Test both paths - Write tests for both when conditions are true and false