- .NET 9.0 SDK or later
To measure actual performance:
cd examples/Linqraft.Benchmark
dotnet run -c ReleaseThe benchmark compares the following patterns:
- Traditional Anonymous - Traditional LINQ Select with anonymous type (baseline)
- Traditional Manual DTO - Traditional LINQ Select with manually defined DTOs
- Linqraft Anonymous - Linqraft
UseLinqraft().Select(...)with anonymous type - Linqraft Auto-Generated DTO - Linqraft
UseLinqraft().Select<TDto>(...)with auto-generated DTOs - Linqraft Manual DTO - Linqraft
UseLinqraft().Select(...)with manually defined DTOs
- AutoMapper ProjectTo - AutoMapper's IQueryable projection with
ProjectTo<T>() - Mapperly Projection - Mapperly's source-generated projection with
ProjectToDto() - Mapster ProjectToType - Mapster's IQueryable projection with
ProjectToType<T>() - Facet ToFacetsAsync - Facet's source-generated DTO projection with
ToFacetsAsync<TSource, TFacet>()
- Uses profile-based configuration
- Requires
MapperConfigurationwithILoggerFactoryparameter (v15 breaking change) - Best for complex mapping scenarios with extensive customization
- Source generator - generates mapping code at compile time
- Zero runtime overhead for mappings
- Requires
[Mapper]attribute on mapper class
- Runtime configuration with
TypeAdapterConfig - Supports both compile-time and runtime mapping
- Good balance between flexibility and performance
- Source generator that creates DTOs and projections from domain models
- Uses
[Facet]attribute on partial record/class withNestedFacetsfor nested objects - Automatic navigation property loading with EF Core
- Uses
ToFacetsAsync<TSource, TFacet>()for better performance