44// Created by: Alexis Kochetov
55// Created: 2009.05.05
66
7- using System ;
87using System . Collections . Generic ;
98using System . Linq ;
109using System . Linq . Expressions ;
1110using System . Reflection ;
12- using Xtensive . Collections ;
1311using Xtensive . Core ;
1412using Xtensive . Orm . Model ;
1513using TypeInfo = Xtensive . Orm . Model . TypeInfo ;
@@ -18,23 +16,24 @@ namespace Xtensive.Orm.Linq.Expressions
1816{
1917 internal class KeyExpression : PersistentFieldExpression
2018 {
21- public TypeInfo EntityType { get ; private set ; }
22- public System . Collections . ObjectModel . ReadOnlyCollection < FieldExpression > KeyFields { get ; private set ; }
19+ public TypeInfo EntityType { get ; }
20+ public IReadOnlyList < FieldExpression > KeyFields { get ; }
2321
2422 public override Expression Remap ( int offset , Dictionary < Expression , Expression > processedExpressions )
2523 {
26- if ( ! CanRemap )
24+ if ( ! CanRemap ) {
2725 return this ;
26+ }
2827
29- Expression value ;
30- if ( processedExpressions . TryGetValue ( this , out value ) )
28+ if ( processedExpressions . TryGetValue ( this , out var value ) ) {
3129 return value ;
30+ }
3231
3332 var mapping = new Segment < int > ( Mapping . Offset + offset , Mapping . Length ) ;
34- var fields = KeyFields
35- . Select ( f => ( FieldExpression ) f . Remap ( offset , processedExpressions ) )
36- . ToList ( )
37- . AsReadOnly ( ) ;
33+
34+ FieldExpression Remap ( FieldExpression f ) => ( FieldExpression ) f . Remap ( offset , processedExpressions ) ;
35+
36+ var fields = KeyFields . Select ( Remap ) . ToArray ( KeyFields . Count ) ;
3837 var result = new KeyExpression ( EntityType , fields , mapping , UnderlyingProperty , OuterParameter , DefaultIfEmpty ) ;
3938
4039 processedExpressions . Add ( this , result ) ;
@@ -43,29 +42,29 @@ public override Expression Remap(int offset, Dictionary<Expression, Expression>
4342
4443 public override Expression Remap ( int [ ] map , Dictionary < Expression , Expression > processedExpressions )
4544 {
46- if ( ! CanRemap )
45+ if ( ! CanRemap ) {
4746 return this ;
47+ }
4848
49- Expression value ;
50- if ( processedExpressions . TryGetValue ( this , out value ) )
49+ if ( processedExpressions . TryGetValue ( this , out var value ) ) {
5150 return value ;
51+ }
5252
5353 var segment = new Segment < int > ( map . IndexOf ( Mapping . Offset ) , Mapping . Length ) ;
54- System . Collections . ObjectModel . ReadOnlyCollection < FieldExpression > fields ;
54+ var fields = new FieldExpression [ KeyFields . Count ] ;
5555 using ( new SkipOwnerCheckScope ( ) ) {
56- fields = KeyFields
57- . Select ( f => f . Remap ( map , processedExpressions ) )
58- . Where ( f => f ! = null )
59- . Cast < FieldExpression > ( )
60- . ToList ( )
61- . AsReadOnly ( ) ;
62- }
63- if ( fields . Count != KeyFields . Count ) {
64- if ( SkipOwnerCheckScope . IsActive ) {
65- processedExpressions . Add ( this , null ) ;
66- return null ;
56+ for ( var index = 0 ; index < fields . Length ; index ++ ) {
57+ var field = ( FieldExpression ) KeyFields [ index ] . Remap ( map , processedExpressions ) ;
58+ if ( field = = null ) {
59+ if ( SkipOwnerCheckScope . IsActive ) {
60+ processedExpressions . Add ( this , null ) ;
61+ return null ;
62+ }
63+ throw Exceptions . InternalError ( Strings . ExUnableToRemapKeyExpression , OrmLog . Instance ) ;
64+ }
65+
66+ fields [ index ] = field ;
6767 }
68- throw Exceptions . InternalError ( Strings . ExUnableToRemapKeyExpression , OrmLog . Instance ) ;
6968 }
7069 var result = new KeyExpression ( EntityType , fields , segment , UnderlyingProperty , OuterParameter , DefaultIfEmpty ) ;
7170
@@ -75,14 +74,14 @@ public override Expression Remap(int[] map, Dictionary<Expression, Expression> p
7574
7675 public override Expression BindParameter ( ParameterExpression parameter , Dictionary < Expression , Expression > processedExpressions )
7776 {
78- Expression value ;
79- if ( processedExpressions . TryGetValue ( this , out value ) )
77+ if ( processedExpressions . TryGetValue ( this , out var value ) ) {
8078 return value ;
79+ }
80+
81+ FieldExpression BindParameter ( FieldExpression f )
82+ => ( FieldExpression ) f . BindParameter ( parameter , processedExpressions ) ;
8183
82- var fields = KeyFields
83- . Select ( f => ( FieldExpression ) f . BindParameter ( parameter , processedExpressions ) )
84- . ToList ( )
85- . AsReadOnly ( ) ;
84+ var fields = KeyFields . Select ( BindParameter ) . ToArray ( KeyFields . Count ) ;
8685 var result = new KeyExpression ( EntityType , fields , Mapping , UnderlyingProperty , parameter , DefaultIfEmpty ) ;
8786
8887 processedExpressions . Add ( this , result ) ;
@@ -91,14 +90,14 @@ public override Expression BindParameter(ParameterExpression parameter, Dictiona
9190
9291 public override Expression RemoveOuterParameter ( Dictionary < Expression , Expression > processedExpressions )
9392 {
94- Expression value ;
95- if ( processedExpressions . TryGetValue ( this , out value ) )
93+ if ( processedExpressions . TryGetValue ( this , out var value ) ) {
9694 return value ;
95+ }
9796
98- var fields = KeyFields
99- . Select ( f => ( FieldExpression ) f . RemoveOuterParameter ( processedExpressions ) )
100- . ToList ( )
101- . AsReadOnly ( ) ;
97+ FieldExpression RemoveOuterParameter ( FieldExpression f )
98+ => ( FieldExpression ) f . RemoveOuterParameter ( processedExpressions ) ;
99+
100+ var fields = KeyFields . Select ( RemoveOuterParameter ) . ToArray ( KeyFields . Count ) ;
102101 var result = new KeyExpression ( EntityType , fields , Mapping , UnderlyingProperty , null , DefaultIfEmpty ) ;
103102
104103 processedExpressions . Add ( this , result ) ;
@@ -108,21 +107,25 @@ public override Expression RemoveOuterParameter(Dictionary<Expression, Expressio
108107 public static KeyExpression Create ( TypeInfo entityType , int offset )
109108 {
110109 var mapping = new Segment < int > ( offset , entityType . Key . TupleDescriptor . Count ) ;
111- var fields = entityType . Columns
112- . Where ( c => c . IsPrimaryKey )
113- . OrderBy ( c => c . Field . MappingInfo . Offset )
114- . Select ( c => FieldExpression . CreateField ( c . Field , offset ) )
115- . ToList ( )
116- . AsReadOnly ( ) ;
117- return new KeyExpression ( entityType , fields , mapping , WellKnownMembers . IEntityKey , null , false ) ;
110+
111+ FieldExpression CreateField ( ColumnInfo c ) => FieldExpression . CreateField ( c . Field , offset ) ;
112+
113+ var fields = entityType . IsLocked
114+ ? entityType . Key . Columns . Select ( CreateField ) . ToArray ( entityType . Key . Columns . Count )
115+ : entityType . Columns
116+ . Where ( c => c . IsPrimaryKey )
117+ . OrderBy ( c => c . Field . MappingInfo . Offset )
118+ . Select ( CreateField )
119+ . ToArray ( ) ;
120+ return new KeyExpression ( entityType , fields , mapping , WellKnownMembers . IEntityKey , null , false ) ;
118121 }
119122
120123
121124 // Constructors
122125
123126 private KeyExpression (
124127 TypeInfo entityType ,
125- System . Collections . ObjectModel . ReadOnlyCollection < FieldExpression > keyFields ,
128+ IReadOnlyList < FieldExpression > keyFields ,
126129 Segment < int > segment ,
127130 PropertyInfo underlyingProperty ,
128131 ParameterExpression parameterExpression ,
0 commit comments