Mapping properties¶
What this does¶
Placing [Map(nameof(Entity.Property))] on a private static partial void method inside a [GenerateFilter<TEntity>] partial exposes that property as filterable. The source generator emits the dispatch and predicate code (per-leaf validation, JSON value extraction, typed Where predicate) for each [Map]-decorated method at compile time.
When to use¶
Any column you want consumers to filter on. The four-method partial below is the minimum viable filter class — declare one [Map] per filterable column on the entity.
Minimal code¶
public sealed class User
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int Age { get; set; }
public bool IsActive { get; set; }
}
[GenerateFilter<User>]
public partial class UserFilter
{
[Map(nameof(User.Id), Sortable = true)] private static partial void MapId();
[Map(nameof(User.Name), Sortable = true)] private static partial void MapName();
[Map(nameof(User.Age), Sortable = true)] private static partial void MapAge();
[Map(nameof(User.IsActive))] private static partial void MapIsActive();
}
The method body is empty — the generator never invokes it; it only reads the attribute. The method is purely a declaration site for the metadata.
Variations¶
Alias = "displayName"— surface the property under a different name in the JSON request.Sortable = true— opt the column into thesortarray. See sortable properties.DefaultSortDirection = SortDir.Desc— flip default direction when consumers sort without specifying one.Profile = typeof(MyProfile)— pick a non-default profile (e.g. a custom[FilterProfile<string>]that adds operators).Only = new[] { "eq", "in" }— allow-list the operators accepted on this property.Except = new[] { "contains" }— deny-list operators inherited from the resolved profile.
Navigation paths use dotted strings: [Map("Department.Name", Alias = "departmentName")].
Pitfalls¶
- The
[Map]-decorated method must be declaredpartial, otherwiseFN0007fires. - A property may be carried by either
[Map]or[PropertyMap], never both —FN0003flags the conflict. - Two
[Map]methods that point at the same property name (or the same alias) collide withFN0001. - The string passed to
[Map(...)]must resolve to a real property on the entity, otherwiseFN0004fires. - Aliases must be unique across the whole filter class (case-insensitive), or
FN0011fires.