Repository navigation
Conversation
3d6476e to
df5ea66
Compare
df5ea66 to
5853c8e
Compare
e5190aa to
81ea00b
Compare
|
Rebased on main |
81ea00b to
f3de520
Compare
|
I have created a modified version with configuration on the This also let you control not-inlining of not-owned code |
9aeaf61 to
8e1ee15
Compare
8e1ee15 to
152f519
Compare
|
Hi, can I do something to finalize this PR? [Mapper]
[UseStaticMapper(typeof(EnumMapper), NoExpressionInlining = true)]
// or:
[UseStaticMapper<EnumMapper>(NoExpressionInlining = true)]
partial class Mapper{}It replaces the: [Mapper]
[UseStaticMapper(typeof(EnumMapper))]
partial class Mapper {}
[Mapper(NoExpressionInlining = true)]
partial class EnumMapper {}What is your opinion? The code for it is here: |
|
@trejjam, this would only allow the setting to be configured for imported mappers, correct? I think we need to support both: setting it on the mapper itself and overriding it for an imported mapper via UseStaticMapper. IMO, the biggest issue with the current implementation is that the setting isn’t resolved correctly from imported mappers. Adding it to |
|
Hello @latonz The new record Source(ESource Value);
record Target(ETarget Value);
record Source2(ESource Value);
record Target2(ETarget Value);
[Mapper]
partial class MapperWithNoExprInlining
{
[MapperNoExpressionInlining]
partial ETarget MapToETarget(ESource source);
partial Target MapToTarget(Source source); // no - inlining allowed for MapToETarget
}
[Mapper]
[UseStaticMapper(typeof(MapperWithNoExprInlining))]
partial class Mapper
{
partial Target2 MapToTarget(Source2 source); // inlined - the inlining is blocked only in the owning MapperWithNoExprInlining
}The record Source(ESource Value);
record Target(ETarget Value);
record Source2(ESource Value);
record Target2(ETarget Value);
[Mapper(NoExpressionInlining = true)]
partial class MapperWithNoExprInlining
{
partial ETarget MapToETarget(ESource source);
partial Target MapToTarget(Source source); // no - inlining allowed for MapToETarget
}
[Mapper]
[UseStaticMapper(typeof(MapperWithNoExprInlining))]
partial class Mapper
{
partial Target2 MapToTarget(Source2 source); // inlined - the inlining is blocked only in the owning MapperWithNoExprInlining
}The record Source(ESource Value);
record Target(ETarget Value);
record Source2(ESource Value);
record Target2(ETarget Value);
[Mapper]
partial class SourcedMapper
{
partial ETarget MapToETarget(ESource source);
partial Target MapToTarget(Source source); // inlining allowed for MapToETarget
}
[Mapper]
[UseStaticMapper(typeof(SourcedMapper), NoExpressionInlining = true)]
partial class Mapper
{
partial Target2 MapToTarget(Source2 source); // MapToETarget is not inlined - the inlining is blocked for SourcedMapper imported methods
}Do you like it to work this way? It should fix the not-scoped configuration read |
|
Thanks for writing up the spec. I don’t particularly like this behavior from a user’s perspective, as it feels a bit unintuitive, but I think it’s the only way to support all three scopes and still resolving the configuration correctly… |
|
I agree, I will modify the PR according to it when I have a spare moment. |
latonz
left a comment
There was a problem hiding this comment.
Implementation of latest spec proposal…
152f519 to
eb71fc6
Compare
eb71fc6 to
f2cc28a
Compare
|
Hi, it should be implemented according to the spec above. |
feat: add
[MapperNoExpressionInliningAttribute]attribute andMapperAttribute.NoExpressionInliningpropertyDescription
When a mapper referenced via
[UseStaticMapper]is used from a mapper that has IQueryable projection methods, Mapperly attempts to inline or rebuild the referenced mapping methods into expression trees. For enum mappings configured withEnumMappingStrategy.ByNamewhere the source and target enums have different underlying types, this rebuild in expression context produces falseRMG037/RMG038diagnostics — reporting all enum members as unmapped even though they match by name.I understand the rationale behind the expression-context restrictions for the general case, and the 5.x alpha series has been catching up and tightening these rules further, which makes sense. However, in my project I was relying on
[UseStaticMapper]with enum-by-name mappings in queryable projections, and the stricter inlining behavior broke that usage. We've discussed the projection + enum + inlining interaction before.This PR adds a general opt-out mechanism for expression-tree inlining:
[MapperNoInlining]— method-level attribute to prevent a specific mapping method from being inlined/rebuilt in expression context[Mapper(NoInlining = true)]— mapper-level property to prevent all methods of a mapper from being inlined when referenced via[UseStaticMapper]Both are applied on the callee mapper (the one being referenced), not the consuming mapper.
Example
When inlining is disabled, the method call is preserved as-is in the expression tree. The ORM evaluates it client-side instead of attempting to translate it to SQL.
Changes
MapperNoExpressionInliningAttributemarker attribute (AttributeTargets.Method)NoExpressionInliningproperty onMapperAttribute(default:false)InlineExpressionMappingBuilderContext.TryInlineMapping()before dispatching to inline/rebuildMapperConfigurationandMapperConfigurationMergerChecklist