-
-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Support IQueryable projection mappings (#287)
- Loading branch information
Showing
109 changed files
with
3,385 additions
and
441 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import Tabs from '@theme/Tabs'; | ||
|
||
# IQueryable projections | ||
|
||
Mapperly does support `IQueryable<T>` projections: | ||
|
||
<!-- do not indent this, it won't work, https://stackoverflow.com/a/67579641/3302887 --> | ||
|
||
<Tabs> | ||
<TabItem value="definition" label="Mapper definition"> | ||
|
||
```csharp | ||
[Mapper] | ||
public static partial class CarMapper | ||
{ | ||
// highlight-start | ||
public static partial IQueryable<CarDto> ProjectToDto(this IQueryable<Car> q); | ||
// highlight-end | ||
} | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="usage" label="Usage"> | ||
|
||
```csharp | ||
var dtos = await DbContext.Cars | ||
.Where(...) | ||
// highlight-start | ||
.ProjectToDto() | ||
// highlight-end | ||
.ToListAsync(); | ||
``` | ||
|
||
</TabItem> | ||
</Tabs> | ||
|
||
This is useful in combination with Entity Framework and other ORM solutions which expose `IQueryable<T>`. | ||
Only fields present in the target class will be retrieved from the database. | ||
|
||
:::info | ||
|
||
Since queryable projection mappings use `System.Linq.Expressions.Expression<T>` under the hood, | ||
such mappings have several limitations: | ||
|
||
- Object factories are not applied | ||
- Constructors with unmatched optional parameters are ignored | ||
- `ThrowOnPropertyMappingNullMismatch` is ignored | ||
- User implemented mappings are not supported | ||
- Enum mappings do not support the `ByName` strategy | ||
- Reference handling is not supported | ||
- Nullable reference types are disabled | ||
|
||
::: | ||
|
||
## Property configurations | ||
|
||
To configure property mappings add partial mapping method definitions with attributes as needed. | ||
Set these methods to private to hide them from callers. | ||
|
||
```csharp | ||
[Mapper] | ||
public static partial class CarMapper | ||
{ | ||
// highlight-start | ||
public static partial IQueryable<CarDto> ProjectToDto(this IQueryable<Car> q); | ||
// highlight-end | ||
// highlight-start | ||
[MapProperty(nameof(Car.Manufacturer), nameof(CarDto.Producer)] | ||
// highlight-end | ||
private static partial CarDto Map(Car car); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Riok.Mapperly.Abstractions; | ||
using Riok.Mapperly.Configuration; | ||
|
||
namespace Riok.Mapperly.Descriptors; | ||
|
||
public class Configuration | ||
{ | ||
/// <summary> | ||
/// Default configurations, used if a configuration is required for a mapping | ||
/// but no configuration is provided by the user. | ||
/// These are the default configurations registered for each configuration attribute (eg. the <see cref="MapEnumAttribute"/>). | ||
/// Usually these are derived from the <see cref="MapperAttribute"/> or default values. | ||
/// </summary> | ||
private readonly Dictionary<Type, Attribute> _defaultConfigurations = new(); | ||
|
||
private readonly Compilation _compilation; | ||
|
||
public Configuration(Compilation compilation, INamedTypeSymbol mapperSymbol) | ||
{ | ||
_compilation = compilation; | ||
Mapper = AttributeDataAccessor.AccessFirstOrDefault<MapperAttribute>(compilation, mapperSymbol) ?? new(); | ||
InitDefaultConfigurations(); | ||
} | ||
|
||
public MapperAttribute Mapper { get; } | ||
|
||
public T GetOrDefault<T>(IMethodSymbol? userSymbol) | ||
where T : Attribute | ||
{ | ||
return ListConfiguration<T>(userSymbol).FirstOrDefault() | ||
?? (T)_defaultConfigurations[typeof(T)]; | ||
} | ||
|
||
public IEnumerable<T> ListConfiguration<T>(IMethodSymbol? userSymbol) | ||
where T : Attribute | ||
{ | ||
return userSymbol == null | ||
? Enumerable.Empty<T>() | ||
: AttributeDataAccessor.Access<T>(_compilation, userSymbol); | ||
} | ||
|
||
private void InitDefaultConfigurations() | ||
{ | ||
_defaultConfigurations.Add( | ||
typeof(MapEnumAttribute), | ||
new MapEnumAttribute(Mapper.EnumMappingStrategy) | ||
{ | ||
IgnoreCase = Mapper.EnumMappingIgnoreCase | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.