@@ -55,6 +55,7 @@ protected ShapedQueryCompilingExpressionVisitor(
55
55
56
56
_structuralTypeMaterializerInjector =
57
57
new StructuralTypeMaterializerInjector (
58
+ this ,
58
59
dependencies . EntityMaterializerSource ,
59
60
dependencies . LiftableConstantFactory ,
60
61
queryCompilationContext . QueryTrackingBehavior ,
@@ -233,12 +234,12 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio
233
234
{
234
235
{ Value : IEntityType entityTypeValue } => liftableConstantFactory . CreateLiftableConstant (
235
236
constantExpression . Value ,
236
- LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForEntityOrComplexType ( entityTypeValue ) ,
237
+ LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForStructuralType ( entityTypeValue ) ,
237
238
entityTypeValue . ShortName ( ) + "EntityType" ,
238
239
constantExpression . Type ) ,
239
240
{ Value : IComplexType complexTypeValue } => liftableConstantFactory . CreateLiftableConstant (
240
241
constantExpression . Value ,
241
- LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForEntityOrComplexType ( complexTypeValue ) ,
242
+ LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForStructuralType ( complexTypeValue ) ,
242
243
complexTypeValue . ShortName ( ) + "ComplexType" ,
243
244
constantExpression . Type ) ,
244
245
{ Value : IProperty propertyValue } => liftableConstantFactory . CreateLiftableConstant (
@@ -361,8 +362,20 @@ protected override Expression VisitExtension(Expression extensionExpression)
361
362
}
362
363
}
363
364
365
+ /// <summary>
366
+ /// Called after a structural type is materialized, but before it's handed off to the change tracker.
367
+ /// </summary>
368
+ public virtual void AddStructuralTypeInitialization (
369
+ StructuralTypeShaperExpression shaper ,
370
+ ParameterExpression instanceVariable ,
371
+ List < ParameterExpression > variables ,
372
+ List < Expression > expressions )
373
+ {
374
+ }
375
+
364
376
private sealed class StructuralTypeMaterializerInjector (
365
- IStructuralTypeMaterializerSource entityMaterializerSource ,
377
+ ShapedQueryCompilingExpressionVisitor shapedQueryCompiler ,
378
+ IStructuralTypeMaterializerSource materializerSource ,
366
379
ILiftableConstantFactory liftableConstantFactory ,
367
380
QueryTrackingBehavior queryTrackingBehavior ,
368
381
bool supportsPrecompiledQuery )
@@ -426,10 +439,10 @@ bool ContainsOwner(IEntityType? owner)
426
439
427
440
protected override Expression VisitExtension ( Expression extensionExpression )
428
441
=> extensionExpression is StructuralTypeShaperExpression shaper
429
- ? ProcessEntityShaper ( shaper )
442
+ ? ProcessStructuralTypeShaper ( shaper )
430
443
: base . VisitExtension ( extensionExpression ) ;
431
444
432
- private Expression ProcessEntityShaper ( StructuralTypeShaperExpression shaper )
445
+ private Expression ProcessStructuralTypeShaper ( StructuralTypeShaperExpression shaper )
433
446
{
434
447
_currentEntityIndex ++ ;
435
448
@@ -565,7 +578,7 @@ private Expression ProcessEntityShaper(StructuralTypeShaperExpression shaper)
565
578
supportsPrecompiledQuery
566
579
? liftableConstantFactory . CreateLiftableConstant (
567
580
typeBase ,
568
- LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForEntityOrComplexType ( typeBase ) ,
581
+ LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForStructuralType ( typeBase ) ,
569
582
typeBase . Name + "EntityType" ,
570
583
typeof ( IEntityType ) )
571
584
: Constant ( typeBase ) ,
@@ -606,7 +619,7 @@ private Expression MaterializeEntity(
606
619
ParameterExpression instanceVariable ,
607
620
ParameterExpression ? entryVariable )
608
621
{
609
- var typeBase = shaper . StructuralType ;
622
+ var structuralType = shaper . StructuralType ;
610
623
611
624
var expressions = new List < Expression > ( ) ;
612
625
var variables = new List < ParameterExpression > ( ) ;
@@ -626,7 +639,7 @@ private Expression MaterializeEntity(
626
639
typeof ( ISnapshot ) )
627
640
: Constant ( Snapshot . Empty , typeof ( ISnapshot ) ) ) ) ;
628
641
629
- var returnType = typeBase . ClrType ;
642
+ var returnType = structuralType . ClrType ;
630
643
var valueBufferExpression = Call ( materializationContextVariable , MaterializationContext . GetValueBufferMethod ) ;
631
644
632
645
var materializationConditionBody = ReplacingExpressionVisitor . Replace (
@@ -637,23 +650,23 @@ private Expression MaterializeEntity(
637
650
var expressionContext = ( returnType , materializationContextVariable , concreteEntityTypeVariable , shadowValuesVariable ) ;
638
651
expressions . Add ( Assign ( concreteEntityTypeVariable , materializationConditionBody ) ) ;
639
652
640
- var ( primaryKey , concreteEntityTypes ) = typeBase is IEntityType entityType
653
+ var ( primaryKey , concreteStructuralTypes ) = structuralType is IEntityType entityType
641
654
? ( entityType . FindPrimaryKey ( ) , entityType . GetConcreteDerivedTypesInclusive ( ) . Cast < ITypeBase > ( ) . ToArray ( ) )
642
- : ( null , [ typeBase ] ) ;
655
+ : ( null , [ structuralType ] ) ;
643
656
644
- var switchCases = new SwitchCase [ concreteEntityTypes . Length ] ;
645
- for ( var i = 0 ; i < concreteEntityTypes . Length ; i ++ )
657
+ var switchCases = new SwitchCase [ concreteStructuralTypes . Length ] ;
658
+ for ( var i = 0 ; i < concreteStructuralTypes . Length ; i ++ )
646
659
{
647
- var concreteEntityType = concreteEntityTypes [ i ] ;
660
+ var concreteStructuralType = concreteStructuralTypes [ i ] ;
648
661
switchCases [ i ] = SwitchCase (
649
- CreateFullMaterializeExpression ( concreteEntityTypes [ i ] , expressionContext ) ,
662
+ CreateFullMaterializeExpression ( concreteStructuralTypes [ i ] , expressionContext ) ,
650
663
supportsPrecompiledQuery
651
664
? liftableConstantFactory . CreateLiftableConstant (
652
- concreteEntityTypes [ i ] ,
653
- LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForEntityOrComplexType ( concreteEntityType ) ,
654
- concreteEntityType . ShortName ( ) + ( typeBase is IEntityType ? "EntityType" : "ComplexType" ) ,
655
- typeBase is IEntityType ? typeof ( IEntityType ) : typeof ( IComplexType ) )
656
- : Constant ( concreteEntityTypes [ i ] , typeBase is IEntityType ? typeof ( IEntityType ) : typeof ( IComplexType ) ) ) ;
665
+ concreteStructuralTypes [ i ] ,
666
+ LiftableConstantExpressionHelpers . BuildMemberAccessLambdaForStructuralType ( concreteStructuralType ) ,
667
+ concreteStructuralType . ShortName ( ) + ( structuralType is IEntityType ? "EntityType" : "ComplexType" ) ,
668
+ structuralType is IEntityType ? typeof ( IEntityType ) : typeof ( IComplexType ) )
669
+ : Constant ( concreteStructuralTypes [ i ] , structuralType is IEntityType ? typeof ( IEntityType ) : typeof ( IComplexType ) ) ) ;
657
670
}
658
671
659
672
var materializationExpression = Switch (
@@ -663,9 +676,11 @@ private Expression MaterializeEntity(
663
676
664
677
expressions . Add ( Assign ( instanceVariable , materializationExpression ) ) ;
665
678
679
+ shapedQueryCompiler . AddStructuralTypeInitialization ( shaper , instanceVariable , variables , expressions ) ;
680
+
666
681
if ( _queryStateManager && primaryKey is not null )
667
682
{
668
- if ( typeBase is IEntityType entityType2 )
683
+ if ( structuralType is IEntityType entityType2 )
669
684
{
670
685
foreach ( var et in entityType2 . GetAllBaseTypes ( ) . Concat ( entityType2 . GetDerivedTypesInclusive ( ) ) )
671
686
{
@@ -696,7 +711,7 @@ private Expression MaterializeEntity(
696
711
}
697
712
698
713
private BlockExpression CreateFullMaterializeExpression (
699
- ITypeBase concreteTypeBase ,
714
+ ITypeBase concreteStructuralType ,
700
715
( Type ReturnType ,
701
716
ParameterExpression MaterializationContextVariable ,
702
717
ParameterExpression ConcreteEntityTypeVariable ,
@@ -709,14 +724,14 @@ private BlockExpression CreateFullMaterializeExpression(
709
724
710
725
var blockExpressions = new List < Expression > ( 2 ) ;
711
726
712
- var materializer = entityMaterializerSource
727
+ var materializer = materializerSource
713
728
. CreateMaterializeExpression (
714
729
new StructuralTypeMaterializerSourceParameters (
715
- concreteTypeBase , "instance" , queryTrackingBehavior ) , materializationContextVariable ) ;
730
+ concreteStructuralType , "instance" , queryTrackingBehavior ) , materializationContextVariable ) ;
716
731
717
732
// TODO: Properly support shadow properties for complex types #35613
718
733
if ( _queryStateManager
719
- && concreteTypeBase is IRuntimeEntityType { ShadowPropertyCount : > 0 } runtimeEntityType )
734
+ && concreteStructuralType is IRuntimeEntityType { ShadowPropertyCount : > 0 } runtimeEntityType )
720
735
{
721
736
var valueBufferExpression = Call (
722
737
materializationContextVariable , MaterializationContext . GetValueBufferMethod ) ;
0 commit comments