1
- // Copyright (C) 2009-2020 Xtensive LLC.
1
+ // Copyright (C) 2009-2021 Xtensive LLC.
2
2
// This code is distributed under MIT license terms.
3
3
// See the License.txt file in the project root for more information.
4
4
// Created by: Alexey Gamzov
@@ -90,8 +90,8 @@ protected override Expression VisitMarker(MarkerExpression expression)
90
90
{
91
91
var target = expression . Target ;
92
92
var processedTarget = Visit ( target ) ;
93
- if ( expression . MarkerType != MarkerType . None && ( expression . MarkerType & MarkerType . Default ) == MarkerType . None ) {
94
- if ( itemMaterializationContextParameter == null )
93
+ if ( expression . MarkerType != MarkerType . None && ( expression . MarkerType & MarkerType . Default ) == MarkerType . None ) {
94
+ if ( itemMaterializationContextParameter == null )
95
95
return processedTarget ;
96
96
var columns = ColumnGatherer . GetColumns ( target , ColumnExtractionModes . Distinct | ColumnExtractionModes . Ordered ) . ToArray ( ) ;
97
97
var sequenceCheck = Expression . Call ( MaterializationHelper . IsNullMethodInfo , tupleParameter , Expression . Constant ( columns ) ) ;
@@ -104,10 +104,8 @@ protected override Expression VisitMarker(MarkerExpression expression)
104
104
protected override Expression VisitGroupingExpression ( GroupingExpression groupingExpression )
105
105
{
106
106
// 1. Prepare subquery parameters.
107
- Parameter < Tuple > parameterOfTuple ;
108
- Type elementType ;
109
- ProjectionExpression projection ;
110
- var translatedQuery = PrepareSubqueryParameters ( groupingExpression , out parameterOfTuple , out elementType , out projection ) ;
107
+ var translatedQuery = PrepareSubqueryParameters ( groupingExpression ,
108
+ out var parameterOfTuple , out var elementType , out var projection ) ;
111
109
112
110
// 2. Create constructor
113
111
var keyType = groupingExpression . KeyExpression . Type ;
@@ -198,7 +196,7 @@ protected override Expression VisitFieldExpression(FieldExpression expression)
198
196
var tupleExpression = GetTupleExpression ( expression ) ;
199
197
200
198
// Materialize non-owned field.
201
- if ( expression . Owner == null || expression . UnderlyingProperty == null ) {
199
+ if ( expression . Owner == null || expression . UnderlyingProperty == null ) {
202
200
if ( expression . Field . IsEnum ) {
203
201
var underlyingType = Enum . GetUnderlyingType ( expression . Type . StripNullable ( ) ) ;
204
202
if ( expression . Field . IsNullable )
@@ -224,28 +222,27 @@ protected override Expression VisitFieldExpression(FieldExpression expression)
224
222
return MaterializeThroughOwner ( expression , tupleExpression ) ;
225
223
}
226
224
227
- protected override Expression VisitLocalCollectionExpression ( LocalCollectionExpression expression )
228
- {
229
- throw new NotSupportedException ( String . Format ( Strings . ExUnableToMaterializeBackLocalCollectionItem , expression . SourceExpression ) ) ;
230
- }
225
+ protected override Expression VisitLocalCollectionExpression ( LocalCollectionExpression expression ) =>
226
+ throw new NotSupportedException (
227
+ string . Format ( Strings . ExUnableToMaterializeBackLocalCollectionItem , expression . SourceExpression ) ) ;
231
228
232
229
protected override Expression VisitStructureFieldExpression ( StructureFieldExpression expression )
233
230
{
234
231
var tupleExpression = GetTupleExpression ( expression ) ;
235
232
236
233
// Materialize non-owned structure.
237
- if ( expression . Owner == null ) {
234
+ if ( expression . Owner == null ) {
238
235
var typeInfo = expression . PersistentType ;
239
236
var tuplePrototype = typeInfo . TuplePrototype ;
240
237
var mappingInfo = expression . Fields
241
238
. OfType < FieldExpression > ( )
242
- . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
239
+ . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
243
240
. OrderBy ( f => f . Field . MappingInfo . Offset )
244
241
. Select ( f => new Pair < int > ( f . Field . MappingInfo . Offset , f . Mapping . Offset ) )
245
242
. Distinct ( )
246
243
. ToArray ( ) ;
247
244
248
- int [ ] columnMap = MaterializationHelper . CreateSingleSourceMap ( tuplePrototype . Count , mappingInfo ) ;
245
+ var columnMap = MaterializationHelper . CreateSingleSourceMap ( tuplePrototype . Count , mappingInfo ) ;
249
246
250
247
var persistentTupleExpression = ( Expression ) Expression . Call (
251
248
BuildPersistentTupleMethod ,
@@ -266,7 +263,7 @@ protected override Expression VisitStructureFieldExpression(StructureFieldExpres
266
263
267
264
protected override Expression VisitConstructorExpression ( ConstructorExpression expression )
268
265
{
269
- var newExpression = expression . Constructor == null
266
+ var newExpression = expression . Constructor == null
270
267
? Expression . New ( expression . Type ) // Value type with default ctor (expression.Constructor is null in that case)
271
268
: Expression . New ( expression . Constructor , expression . ConstructorArguments . Select ( Visit ) ) ;
272
269
@@ -275,9 +272,9 @@ protected override Expression VisitConstructorExpression(ConstructorExpression e
275
272
return expression . NativeBindings . Count == 0
276
273
? newExpression
277
274
: ( Expression ) Expression . MemberInit ( newExpression , expression
278
- . NativeBindings
279
- . Where ( item => Translator . FilterBindings ( item . Key , item . Key . Name , item . Value . Type ) )
280
- . Select ( item => Expression . Bind ( item . Key , Visit ( item . Value ) ) ) . Cast < MemberBinding > ( ) ) ;
275
+ . NativeBindings
276
+ . Where ( item => Translator . FilterBindings ( item . Key , item . Key . Name , item . Value . Type ) )
277
+ . Select ( item => Expression . Bind ( item . Key , Visit ( item . Value ) ) ) . Cast < MemberBinding > ( ) ) ;
281
278
}
282
279
283
280
protected override Expression VisitStructureExpression ( StructureExpression expression )
@@ -288,13 +285,13 @@ protected override Expression VisitStructureExpression(StructureExpression expre
288
285
var tuplePrototype = typeInfo . TuplePrototype ;
289
286
var mappingInfo = expression . Fields
290
287
. OfType < FieldExpression > ( )
291
- . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
288
+ . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
292
289
. OrderBy ( f => f . Field . MappingInfo . Offset )
293
290
. Select ( f => new Pair < int > ( f . Field . MappingInfo . Offset , f . Mapping . Offset ) )
294
291
. Distinct ( )
295
292
. ToArray ( ) ;
296
293
297
- int [ ] columnMap = MaterializationHelper . CreateSingleSourceMap ( tuplePrototype . Count , mappingInfo ) ;
294
+ var columnMap = MaterializationHelper . CreateSingleSourceMap ( tuplePrototype . Count , mappingInfo ) ;
298
295
299
296
var persistentTupleExpression = ( Expression ) Expression . Call (
300
297
BuildPersistentTupleMethod ,
@@ -337,21 +334,23 @@ protected override Expression VisitEntityExpression(EntityExpression expression)
337
334
/// <exception cref="InvalidOperationException">Unable to materialize Entity.</exception>
338
335
private Expression CreateEntity ( IEntityExpression expression , Expression tupleExpression )
339
336
{
340
- int index ;
341
- if ( ! entityRegistry . TryGetValue ( expression , out index ) ) {
337
+ if ( ! entityRegistry . TryGetValue ( expression , out var index ) ) {
342
338
index = entityRegistry . Count ;
343
339
entityRegistry . Add ( expression , index ) ;
344
340
}
345
341
346
- if ( itemMaterializationContextParameter == null )
347
- throw new InvalidOperationException ( String . Format ( Strings . ExUnableToTranslateLambdaExpressionXBecauseItRequiresToMaterializeEntityOfTypeX , context . Translator . state . CurrentLambda , expression . PersistentType . UnderlyingType . FullName ) ) ;
342
+ if ( itemMaterializationContextParameter == null )
343
+ throw new InvalidOperationException (
344
+ string . Format ( Strings . ExUnableToTranslateLambdaExpressionXBecauseItRequiresToMaterializeEntityOfTypeX ,
345
+ context . Translator . state . CurrentLambda ,
346
+ expression . PersistentType . UnderlyingType . FullName ) ) ;
348
347
349
- var typeIdField = expression . Fields . SingleOrDefault ( f => f . Name == WellKnown . TypeIdFieldName ) ;
350
- int typeIdIndex = typeIdField == null ? - 1 : typeIdField . Mapping . Offset ;
348
+ var typeIdField = expression . Fields . SingleOrDefault ( f => f . Name == WellKnown . TypeIdFieldName ) ;
349
+ var typeIdIndex = typeIdField == null ? - 1 : typeIdField . Mapping . Offset ;
351
350
352
351
var mappingInfo = expression . Fields
353
352
. OfType < FieldExpression > ( )
354
- . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
353
+ . Where ( f => f . ExtendedType == ExtendedExpressionType . Field )
355
354
. OrderBy ( f => f . Field . MappingInfo . Offset )
356
355
. Select ( f => new Pair < int > ( f . Field . MappingInfo . Offset , f . Mapping . Offset ) )
357
356
. Distinct ( )
@@ -384,13 +383,13 @@ private Expression CreateEntity(IEntityExpression expression, Expression tupleEx
384
383
/// <exception cref="InvalidOperationException"><c>InvalidOperationException</c>.</exception>
385
384
protected override Expression VisitEntityFieldExpression ( EntityFieldExpression expression )
386
385
{
387
- if ( expression . Entity != null )
386
+ if ( expression . Entity != null )
388
387
return Visit ( expression . Entity ) ;
389
388
390
389
var tupleExpression = GetTupleExpression ( expression ) ;
391
- if ( itemMaterializationContextParameter == null )
392
- return tupleExpression . MakeTupleAccess ( expression . Type , expression . Mapping . Offset ) ;
393
- return CreateEntity ( expression , tupleExpression ) ;
390
+ return itemMaterializationContextParameter == null
391
+ ? tupleExpression . MakeTupleAccess ( expression . Type , expression . Mapping . Offset )
392
+ : CreateEntity ( expression , tupleExpression ) ;
394
393
}
395
394
396
395
protected override Expression VisitEntitySetExpression ( EntitySetExpression expression )
@@ -432,21 +431,18 @@ protected override Expression VisitUnary(UnaryExpression u)
432
431
var index = tupleAccess . GetTupleAccessArgument ( ) ;
433
432
return tupleAccess . Object . MakeTupleAccess ( u . Type , index ) ;
434
433
}
435
- if ( operand != u . Operand ) {
436
- return Expression . Convert ( operand , u . Type ) ;
437
- }
438
- return u ;
434
+ return operand != u . Operand ? Expression . Convert ( operand , u . Type ) : u ;
439
435
}
440
436
return base . VisitUnary ( u ) ;
441
437
}
442
438
443
439
protected override Expression VisitMemberAccess ( MemberExpression m )
444
440
{
445
- if ( m . Expression != null ) {
446
- if ( ( ExtendedExpressionType ) m . Expression . NodeType == ExtendedExpressionType . LocalCollection ) {
441
+ if ( m . Expression != null ) {
442
+ if ( ( ExtendedExpressionType ) m . Expression . NodeType == ExtendedExpressionType . LocalCollection ) {
447
443
return Visit ( ( Expression ) ( ( LocalCollectionExpression ) m . Expression ) . Fields [ m . Member ] ) ;
448
444
}
449
- if ( itemMaterializationContextParameter != null
445
+ if ( itemMaterializationContextParameter != null
450
446
&& string . Equals ( nameof ( Parameter < object > . Value ) , m . Member . Name , StringComparison . Ordinal )
451
447
&& WellKnownOrmTypes . Parameter . IsAssignableFrom ( m . Expression . Type ) ) {
452
448
var parameterType = m . Expression . Type ;
@@ -460,7 +456,7 @@ protected override Expression VisitMemberAccess(MemberExpression m)
460
456
}
461
457
462
458
var expression = Visit ( m . Expression ) ;
463
- if ( expression == m . Expression ) {
459
+ if ( expression == m . Expression ) {
464
460
return m ;
465
461
}
466
462
@@ -471,15 +467,12 @@ protected override Expression VisitMemberAccess(MemberExpression m)
471
467
472
468
#region Private Methods
473
469
474
- private Expression MaterializeThroughOwner ( Expression target , Expression tuple )
475
- {
476
- return MaterializeThroughOwner ( target , tuple , false ) ;
477
- }
470
+ private Expression MaterializeThroughOwner ( Expression target , Expression tuple ) =>
471
+ MaterializeThroughOwner ( target , tuple , false ) ;
478
472
479
473
private Expression MaterializeThroughOwner ( Expression target , Expression tuple , bool defaultIfEmpty )
480
474
{
481
- var field = target as FieldExpression ;
482
- if ( field != null ) {
475
+ if ( target is FieldExpression field ) {
483
476
defaultIfEmpty |= field . DefaultIfEmpty ;
484
477
var owner = field . Owner ;
485
478
var materializedOwner = MaterializeThroughOwner ( ( Expression ) owner , tuple , defaultIfEmpty ) ;
@@ -492,20 +485,19 @@ private Expression MaterializeThroughOwner(Expression target, Expression tuple,
492
485
}
493
486
else
494
487
fieldExpression = Expression . MakeMemberAccess ( materializedOwner , field . Field . UnderlyingProperty ) ;
495
- if ( defaultIfEmpty ) {
496
- return Expression . Condition (
497
- Expression . Equal ( materializedOwner , Expression . Constant ( null , materializedOwner . Type ) ) ,
498
- Expression . Call ( MaterializationHelper . GetDefaultMethodInfo . MakeGenericMethod ( field . Type ) ) ,
499
- fieldExpression ) ;
500
- }
501
- return fieldExpression ;
488
+ return defaultIfEmpty
489
+ ? Expression . Condition (
490
+ Expression . Equal ( materializedOwner , Expression . Constant ( null , materializedOwner . Type ) ) ,
491
+ Expression . Call ( MaterializationHelper . GetDefaultMethodInfo . MakeGenericMethod ( field . Type ) ) ,
492
+ fieldExpression )
493
+ : fieldExpression ;
502
494
}
503
495
return CreateEntity ( ( EntityExpression ) target , tuple ) ;
504
496
}
505
497
506
498
private Expression GetTupleExpression ( ParameterizedExpression expression )
507
499
{
508
- if ( expression . OuterParameter == null )
500
+ if ( expression . OuterParameter == null )
509
501
return tupleParameter ;
510
502
511
503
var parameterOfTuple = context . GetTupleParameter ( expression . OuterParameter ) ;
@@ -517,7 +509,7 @@ private Expression GetTupleExpression(ParameterizedExpression expression)
517
509
}
518
510
519
511
// Use ApplyParameter for RecordSet predicates
520
- if ( itemMaterializationContextParameter == null ) {
512
+ if ( itemMaterializationContextParameter == null ) {
521
513
var projectionExpression = context . Bindings [ expression . OuterParameter ] ;
522
514
var applyParameter = context . GetApplyParameter ( projectionExpression ) ;
523
515
var applyParameterExpression = Expression . Constant ( applyParameter ) ;
@@ -527,21 +519,14 @@ private Expression GetTupleExpression(ParameterizedExpression expression)
527
519
return tupleParameter ;
528
520
}
529
521
530
- // ReSharper disable UnusedMember.Local
531
-
532
522
private static Tuple BuildPersistentTuple ( Tuple tuple , Tuple tuplePrototype , int [ ] mapping )
533
523
{
534
524
var result = tuplePrototype . CreateNew ( ) ;
535
525
tuple . CopyTo ( result , mapping ) ;
536
526
return result ;
537
527
}
538
528
539
- private static Tuple GetTupleSegment ( Tuple tuple , in Segment < int > segment )
540
- {
541
- return tuple . GetSegment ( segment ) . ToRegular ( ) ;
542
- }
543
-
544
- // ReSharper restore UnusedMember.Local
529
+ private static Tuple GetTupleSegment ( Tuple tuple , in Segment < int > segment ) => tuple . GetSegment ( segment ) . ToRegular ( ) ;
545
530
546
531
#endregion
547
532
@@ -561,12 +546,14 @@ private ExpressionMaterializer(ParameterExpression
561
546
562
547
static ExpressionMaterializer ( )
563
548
{
549
+ var thisType = typeof ( ExpressionMaterializer ) ;
550
+
564
551
ParameterContextProperty =
565
552
WellKnownOrmTypes . ItemMaterializationContext . GetProperty ( nameof ( ItemMaterializationContext . ParameterContext ) ) ;
566
553
GetParameterValueMethod = WellKnownOrmTypes . ParameterContext . GetMethod ( nameof ( ParameterContext . GetValue ) ) ;
567
554
GetTupleParameterValueMethod = GetParameterValueMethod . MakeGenericMethod ( WellKnownOrmTypes . Tuple ) ;
568
- BuildPersistentTupleMethod = typeof ( ExpressionMaterializer ) . GetMethod ( " BuildPersistentTuple" , BindingFlags . NonPublic | BindingFlags . Static ) ;
569
- GetTupleSegmentMethod = typeof ( ExpressionMaterializer ) . GetMethod ( " GetTupleSegment" , BindingFlags . NonPublic | BindingFlags . Static ) ;
555
+ BuildPersistentTupleMethod = thisType . GetMethod ( nameof ( BuildPersistentTuple ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
556
+ GetTupleSegmentMethod = thisType . GetMethod ( nameof ( GetTupleSegment ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
570
557
}
571
558
}
572
559
}
0 commit comments