55// Created: 2009.11.13
66
77using System ;
8+ using System . Collections . Concurrent ;
89using System . Collections . Generic ;
910using System . Linq ;
1011using System . Linq . Expressions ;
1718using Xtensive . Sql ;
1819using Xtensive . Sql . Dml ;
1920using IndexInfo = Xtensive . Orm . Model . IndexInfo ;
21+ using TypeMapping = Xtensive . Sql . TypeMapping ;
2022
2123namespace Xtensive . Orm . Providers
2224{
@@ -39,6 +41,13 @@ public QueryAndBindings(SqlSelect initialQuery, List<QueryParameterBinding> bind
3941 }
4042 }
4143
44+ private static readonly ConcurrentDictionary < int , Func < ParameterContext , object > > typeIdParameterAccessorCache =
45+ new ConcurrentDictionary < int , Func < ParameterContext , object > > ( ) ;
46+
47+ private static readonly Func < int , Func < ParameterContext , object > > AccessorFactory = typeId => _ => typeId ;
48+
49+ private TypeMapping int32TypeMapping ;
50+
4251 protected override SqlProvider VisitFreeText ( FreeTextProvider provider )
4352 {
4453 throw new NotSupportedException ( ) ;
@@ -249,20 +258,15 @@ private QueryAndBindings BuildFilteredQuery(IndexInfo index)
249258 SqlDml . Array ( filterByTypes . Select ( t => TypeIdRegistry [ t ] ) . ToArray ( filterByTypes . Count ) ) ) ;
250259 }
251260 else {
252- var typeMapping = Driver . GetTypeMapping ( WellKnownTypes . Int32 ) ;
253261 if ( filterByTypes . Count == 1 ) {
254- var binding = new QueryParameterBinding ( typeMapping ,
255- CreateTypeIdAccessor ( TypeIdRegistry [ type ] ) . CachingCompile ( ) ,
256- QueryParameterBindingType . Regular ) ;
262+ var binding = CreateQueryParameterBinding ( type ) ;
257263 bindings . Add ( binding ) ;
258264 filter = typeIdColumn == binding . ParameterReference ;
259265 }
260266 else {
261267 var typeIdParameters = filterByTypes
262268 . Select ( t => {
263- var binding = new QueryParameterBinding ( typeMapping ,
264- CreateTypeIdAccessor ( TypeIdRegistry [ t ] ) . CachingCompile ( ) ,
265- QueryParameterBindingType . Regular ) ;
269+ var binding = CreateQueryParameterBinding ( t ) ;
266270 bindings . Add ( binding ) ;
267271 return binding . ParameterReference ;
268272 } )
@@ -308,8 +312,7 @@ private QueryAndBindings BuildTypedQuery(IndexInfo index)
308312
309313 SqlUserColumn typeIdColumn ;
310314 if ( useParameterForTypeId ) {
311- var typeMapping = Driver . GetTypeMapping ( WellKnownTypes . Int32 ) ;
312- var binding = new QueryParameterBinding ( typeMapping , CreateTypeIdAccessor ( TypeIdRegistry [ type ] ) . CachingCompile ( ) , QueryParameterBindingType . Regular ) ;
315+ var binding = CreateQueryParameterBinding ( type ) ;
313316
314317 typeIdColumn = SqlDml . Column ( binding . ParameterReference ) ;
315318 bindings . Add ( binding ) ;
@@ -352,11 +355,11 @@ private object GetDiscriminatorValue(TypeDiscriminatorMap discriminatorMap, obje
352355 : fieldValue ;
353356 }
354357
355- private Expression < Func < ParameterContext , object > > CreateTypeIdAccessor ( int value )
356- {
357- var bodyExpression = Expression . Convert ( Expression . Constant ( value ) , WellKnownTypes . Object ) ;
358- var lambdaParemeter = Expression . Parameter ( WellKnownOrmTypes . ParameterContext , "context" ) ;
359- return ( Expression < Func < ParameterContext , object > > ) FastExpression . Lambda ( bodyExpression , lambdaParemeter ) ;
360- }
358+ private QueryParameterBinding CreateQueryParameterBinding ( TypeInfo type ) =>
359+ new QueryParameterBinding (
360+ int32TypeMapping ??= Driver . GetTypeMapping ( WellKnownTypes . Int32 ) ,
361+ typeIdParameterAccessorCache . GetOrAdd ( TypeIdRegistry [ type ] , AccessorFactory ) ,
362+ QueryParameterBindingType . Regular
363+ ) ;
361364 }
362365}
0 commit comments