Skip to content

Commit 63f69df

Browse files
authored
Use covariant types in BindParameter() (#415)
* Use covariant types in `BindParameter()` * Continue
1 parent dee51ed commit 63f69df

17 files changed

+69
-106
lines changed

Orm/Xtensive.Orm/Orm/Linq/Expressions/ColumnExpression.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,16 @@ public override ColumnExpression Remap(ColumnMap map, Dictionary<Expression, Exp
3232
return new ColumnExpression(Type, newMapping, OuterParameter, DefaultIfEmpty);
3333
}
3434

35-
public Expression BindParameter(ParameterExpression parameter)
36-
{
37-
return BindParameter(parameter, new Dictionary<Expression, Expression>());
38-
}
35+
public ColumnExpression BindParameter(ParameterExpression parameter) =>
36+
BindParameter(parameter, new Dictionary<Expression, Expression>());
3937

4038
public override ColumnExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
4139
{
4240
return new ColumnExpression(Type, Mapping, parameter, DefaultIfEmpty);
4341
}
4442

45-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
46-
{
47-
return new ColumnExpression(Type, Mapping, null, DefaultIfEmpty);
48-
}
43+
public override ColumnExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions) =>
44+
new(Type, Mapping, null, DefaultIfEmpty);
4945

5046
public static ColumnExpression Create(Type type, ColNum columnIndex)
5147
{
@@ -72,4 +68,4 @@ private ColumnExpression(
7268
this.Mapping = mapping;
7369
}
7470
}
75-
}
71+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/ConstructorExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal sealed class ConstructorExpression : ParameterizedExpression
2828

2929
public IReadOnlyList<Expression> ConstructorArguments { get; }
3030

31-
public override Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
31+
public override ParameterizedExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
3232
{
3333
GenericExpressionVisitor<IMappedExpression> genericVisitor = new(mapped => mapped.BindParameter(parameter, processedExpressions));
3434
var genericBinder = genericVisitor.Process;

Orm/Xtensive.Orm/Orm/Linq/Expressions/EntityExpression.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ public override EntityExpression Remap(ColumnMap map, Dictionary<Expression, Exp
7676
return result;
7777
}
7878

79-
public override Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
79+
public override EntityExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
8080
{
8181
if (processedExpressions.TryGetValue(this, out var value)) {
82-
return value;
82+
return (EntityExpression) value;
8383
}
8484

85-
var keyExpression = (KeyExpression) Key.BindParameter(parameter, processedExpressions);
85+
var keyExpression = Key.BindParameter(parameter, processedExpressions);
8686
var result = new EntityExpression(PersistentType, keyExpression, parameter, DefaultIfEmpty);
8787
result.IsNullable = IsNullable;
8888
processedExpressions.Add(this, result);
@@ -96,13 +96,13 @@ public override Expression BindParameter(ParameterExpression parameter, Dictiona
9696
return result;
9797
}
9898

99-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
99+
public override EntityExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
100100
{
101101
if (processedExpressions.TryGetValue(this, out var value)) {
102-
return value;
102+
return (EntityExpression) value;
103103
}
104104

105-
var keyExpression = (KeyExpression) Key.RemoveOuterParameter(processedExpressions);
105+
var keyExpression = Key.RemoveOuterParameter(processedExpressions);
106106
var result = new EntityExpression(PersistentType, keyExpression, null, DefaultIfEmpty);
107107
result.IsNullable = IsNullable;
108108
processedExpressions.Add(this, result);
@@ -177,7 +177,7 @@ public static EntityExpression Create(EntityFieldExpression entityFieldExpressio
177177
result.SetFields(fields);
178178
return entityFieldExpression.OuterParameter == null
179179
? result
180-
: (EntityExpression) result.BindParameter(
180+
: result.BindParameter(
181181
entityFieldExpression.OuterParameter, new Dictionary<Expression, Expression>());
182182
}
183183

Orm/Xtensive.Orm/Orm/Linq/Expressions/EntityFieldExpression.cs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
// Created by: Alexis Kochetov
55
// Created: 2009.05.06
66

7-
using System;
8-
using System.Collections.Generic;
97
using System.Linq.Expressions;
108
using Xtensive.Core;
119
using Xtensive.Orm.Model;
@@ -103,14 +101,14 @@ public override EntityFieldExpression BindParameter(
103101
return (EntityFieldExpression)r;
104102
}
105103

106-
var newFields = new PersistentFieldExpression[fields.Count];
107-
int i = 0;
108-
foreach (var field in fields) {
104+
var n = fields.Count;
105+
var newFields = new PersistentFieldExpression[n];
106+
for (int i = 0; i < n; ++i) {
109107
// Do not convert to LINQ. We want to avoid a closure creation here.
110-
newFields[i++] = (PersistentFieldExpression) field.BindParameter(parameter, processedExpressions);
108+
newFields[i] = (PersistentFieldExpression) fields[i].BindParameter(parameter, processedExpressions);
111109
}
112-
var keyExpression = (KeyExpression) Key.BindParameter(parameter, processedExpressions);
113-
var entity = (EntityExpression) Entity?.BindParameter(parameter, processedExpressions);
110+
var keyExpression = Key.BindParameter(parameter, processedExpressions);
111+
var entity = Entity?.BindParameter(parameter, processedExpressions);
114112
var result = new EntityFieldExpression(
115113
PersistentType, Field, newFields, Mapping, keyExpression, entity, parameter, DefaultIfEmpty);
116114
if (Owner == null) {
@@ -122,20 +120,21 @@ public override EntityFieldExpression BindParameter(
122120
return result;
123121
}
124122

125-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
123+
public override EntityFieldExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
126124
{
127-
if (processedExpressions.TryGetValue(this, out var result)) {
128-
return result;
125+
if (processedExpressions.TryGetValue(this, out var value)) {
126+
return (EntityFieldExpression) value;
129127
}
130128

131-
var newFields = new List<PersistentFieldExpression>(fields.Count);
129+
var newFields = new PersistentFieldExpression[fields.Count];
130+
int i = 0;
132131
foreach (var field in fields) {
133132
// Do not convert to LINQ. We want to avoid a closure creation here.
134-
newFields.Add((PersistentFieldExpression) field.RemoveOuterParameter(processedExpressions));
133+
newFields[i++] = (PersistentFieldExpression) field.RemoveOuterParameter(processedExpressions);
135134
}
136-
var keyExpression = (KeyExpression) Key.RemoveOuterParameter(processedExpressions);
137-
var entity = (EntityExpression) Entity?.RemoveOuterParameter(processedExpressions);
138-
result = new EntityFieldExpression(
135+
var keyExpression = Key.RemoveOuterParameter(processedExpressions);
136+
var entity = Entity?.RemoveOuterParameter(processedExpressions);
137+
var result = new EntityFieldExpression(
139138
PersistentType, Field, newFields, Mapping, keyExpression, entity, null, DefaultIfEmpty);
140139
if (Owner == null) {
141140
return result;

Orm/Xtensive.Orm/Orm/Linq/Expressions/EntitySetExpression.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,11 @@ public override EntitySetExpression BindParameter(ParameterExpression parameter,
8787
return result;
8888
}
8989

90-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
90+
public override EntitySetExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
9191
{
92-
Expression result;
93-
if (processedExpressions.TryGetValue(this, out result))
94-
return result;
95-
result = new EntitySetExpression(Field, null, DefaultIfEmpty);
92+
if (processedExpressions.TryGetValue(this, out var value))
93+
return (EntitySetExpression) value;
94+
var result = new EntitySetExpression(Field, null, DefaultIfEmpty);
9695
if (base.Owner==null)
9796
return result;
9897
processedExpressions.Add(this, result);
@@ -122,4 +121,4 @@ private EntitySetExpression(
122121
{
123122
}
124123
}
125-
}
124+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/FieldExpression.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ public override FieldExpression BindParameter(ParameterExpression parameter, Dic
9090
return result;
9191
}
9292

93-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
93+
public override FieldExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
9494
{
95-
if (processedExpressions.TryGetValue(this, out var result)) {
96-
return result;
95+
if (processedExpressions.TryGetValue(this, out var value)) {
96+
return (FieldExpression) value;
9797
}
9898

99-
result = new FieldExpression(ExtendedExpressionType.Field, Field, Mapping, null, DefaultIfEmpty);
99+
var result = new FieldExpression(ExtendedExpressionType.Field, Field, Mapping, null, DefaultIfEmpty);
100100
if (owner == null) {
101101
return result;
102102
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/FullTextExpression.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ internal sealed class FullTextExpression : ParameterizedExpression
2424

2525
public EntityExpression EntityExpression { get; private set; }
2626

27-
public override Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
27+
public override ParameterizedExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
2828
{
2929
Expression result;
3030
if (processedExpressions.TryGetValue(this, out result))
31-
return result;
31+
return (ParameterizedExpression) result;
3232

33-
var entityExpression = (EntityExpression) EntityExpression.BindParameter(parameter, processedExpressions);
34-
var rankExpression = (ColumnExpression) RankExpression.BindParameter(parameter, processedExpressions);
33+
var entityExpression = EntityExpression.BindParameter(parameter, processedExpressions);
34+
var rankExpression = RankExpression.BindParameter(parameter, processedExpressions);
3535
return new FullTextExpression(FullTextIndex, entityExpression, rankExpression, parameter);
3636
}
3737

@@ -41,8 +41,8 @@ public override Expression RemoveOuterParameter(Dictionary<Expression, Expressio
4141
if (processedExpressions.TryGetValue(this, out result))
4242
return result;
4343

44-
var entityExpression = (EntityExpression) EntityExpression.RemoveOuterParameter(processedExpressions);
45-
var rankExpression = (ColumnExpression) RankExpression.RemoveOuterParameter(processedExpressions);
44+
var entityExpression = EntityExpression.RemoveOuterParameter(processedExpressions);
45+
var rankExpression = RankExpression.RemoveOuterParameter(processedExpressions);
4646
return new FullTextExpression(FullTextIndex, entityExpression, rankExpression, null);
4747
}
4848

@@ -84,4 +84,4 @@ public FullTextExpression(FullTextIndexInfo fullTextIndex, EntityExpression enti
8484
EntityExpression = entityExpression;
8585
}
8686
}
87-
}
87+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/GroupingExpression.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,14 @@ public SelectManyGroupingInfo(ProjectionExpression groupByProjection)
4242

4343
public SelectManyGroupingInfo SelectManyInfo { get; private set; }
4444

45-
public override Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
45+
public override ParameterizedExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
4646
{
47-
Expression result;
48-
if (processedExpressions.TryGetValue(this, out result))
49-
return result;
50-
var mappedKey = KeyExpression as IMappedExpression;
51-
if (mappedKey==null)
47+
if (processedExpressions.TryGetValue(this, out var value))
48+
return (ParameterizedExpression) value;
49+
if (!(KeyExpression is IMappedExpression mappedKey))
5250
return this;
5351
var processedKey = mappedKey.BindParameter(parameter, processedExpressions);
54-
result = new GroupingExpression(Type, OuterParameter, DefaultIfEmpty, ProjectionExpression, ApplyParameter, processedKey, SelectManyInfo);
52+
var result = new GroupingExpression(Type, OuterParameter, DefaultIfEmpty, ProjectionExpression, ApplyParameter, processedKey, SelectManyInfo);
5553
processedExpressions.Add(this, result);
5654
return result;
5755
}
@@ -110,4 +108,4 @@ public GroupingExpression(
110108
KeyExpression = keyExpression;
111109
}
112110
}
113-
}
111+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/Interfaces/IMappedExpression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ namespace Xtensive.Orm.Linq.Expressions
1212
{
1313
internal interface IMappedExpression
1414
{
15-
Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions);
15+
ParameterizedExpression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions);
1616
Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions);
1717
Expression Remap(ColNum offset, Dictionary<Expression, Expression> processedExpressions);
1818
Expression Remap(ColumnMap map, Dictionary<Expression, Expression> processedExpressions);
1919
}
20-
}
20+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/KeyExpression.cs

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@ public override KeyExpression Remap(ColNum offset, Dictionary<Expression, Expres
2525
{
2626
if (TryProcessed<KeyExpression>(processedExpressions, out var value))
2727
return value;
28-
return RemapWithNoCheck(offset, processedExpressions);
29-
}
30-
31-
// Having this code as a separate method helps to avoid closure allocation during Remap call
32-
// in case processedExpressions dictionary already contains a result.
33-
private KeyExpression RemapWithNoCheck(ColNum offset, Dictionary<Expression, Expression> processedExpressions)
34-
{
3528
var newMapping = new Segment<ColNum>((ColNum)(Mapping.Offset + offset), Mapping.Length);
3629

3730
var n = KeyFields.Count;
@@ -79,14 +72,6 @@ public override KeyExpression BindParameter(
7972
return (KeyExpression)value;
8073
}
8174

82-
return BindParameterWithNoCheck(parameter, processedExpressions);
83-
}
84-
85-
// Having this code as a separate method helps to avoid closure allocation during BindParameter call
86-
// in case processedExpressions dictionary already contains a result.
87-
private KeyExpression BindParameterWithNoCheck(
88-
ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
89-
{
9075
var n = KeyFields.Count;
9176
var fields = new FieldExpression[n];
9277
for (int i = 0; i < n; ++i) {
@@ -98,23 +83,16 @@ private KeyExpression BindParameterWithNoCheck(
9883
return result;
9984
}
10085

101-
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
86+
public override KeyExpression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
10287
{
10388
if (processedExpressions.TryGetValue(this, out var value)) {
104-
return value;
89+
return (KeyExpression) value;
10590
}
10691

107-
return RemoveOuterParameterWithNoCheck(processedExpressions);
108-
}
109-
110-
// Having this code as a separate method helps to avoid closure allocation during RemoveOuterParameter call
111-
// in case processedExpressions dictionary already contains a result.
112-
private Expression RemoveOuterParameterWithNoCheck(Dictionary<Expression, Expression> processedExpressions)
113-
{
11492
var n = KeyFields.Count;
11593
var fields = new FieldExpression[n];
11694
for (int i = 0; i < n; ++i) {
117-
fields[i] = (FieldExpression) KeyFields[i].RemoveOuterParameter(processedExpressions);
95+
fields[i] = KeyFields[i].RemoveOuterParameter(processedExpressions);
11896
}
11997
var result = new KeyExpression(EntityType, fields, Mapping, UnderlyingProperty, null, DefaultIfEmpty);
12098

@@ -155,4 +133,4 @@ private KeyExpression(
155133
KeyFields = keyFields;
156134
}
157135
}
158-
}
136+
}

0 commit comments

Comments
 (0)