@@ -9,31 +9,22 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime.Query.Internal;
99/// <remarks>
1010/// See: https://www.postgresql.org/docs/current/static/functions-datetime.html
1111/// </remarks>
12- public class NpgsqlNodaTimeMemberTranslatorPlugin : IMemberTranslatorPlugin
12+ public class NpgsqlNodaTimeMemberTranslatorPlugin (
13+ IRelationalTypeMappingSource typeMappingSource ,
14+ ISqlExpressionFactory sqlExpressionFactory )
15+ : IMemberTranslatorPlugin
1316{
17+
1418 /// <summary>
1519 /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
1620 /// the same compatibility standards as public APIs. It may be changed or removed without notice in
1721 /// any release. You should only use it directly in your code with extreme caution and knowing that
1822 /// doing so can result in application failures when updating to a new Entity Framework Core release.
1923 /// </summary>
20- public NpgsqlNodaTimeMemberTranslatorPlugin (
21- IRelationalTypeMappingSource typeMappingSource ,
22- ISqlExpressionFactory sqlExpressionFactory )
23- {
24- Translators =
24+ public virtual IEnumerable < IMemberTranslator > Translators { get ; } =
2525 [
2626 new NpgsqlNodaTimeMemberTranslator ( typeMappingSource , ( NpgsqlSqlExpressionFactory ) sqlExpressionFactory )
2727 ] ;
28- }
29-
30- /// <summary>
31- /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
32- /// the same compatibility standards as public APIs. It may be changed or removed without notice in
33- /// any release. You should only use it directly in your code with extreme caution and knowing that
34- /// doing so can result in application failures when updating to a new Entity Framework Core release.
35- /// </summary>
36- public virtual IEnumerable < IMemberTranslator > Translators { get ; }
3728}
3829
3930/// <summary>
@@ -42,64 +33,22 @@ public NpgsqlNodaTimeMemberTranslatorPlugin(
4233/// any release. You should only use it directly in your code with extreme caution and knowing that
4334/// doing so can result in application failures when updating to a new Entity Framework Core release.
4435/// </summary>
45- public class NpgsqlNodaTimeMemberTranslator : IMemberTranslator
36+ /// <remarks>
37+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
38+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
39+ /// any release. You should only use it directly in your code with extreme caution and knowing that
40+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
41+ /// </remarks>
42+ public class NpgsqlNodaTimeMemberTranslator (
43+ IRelationalTypeMappingSource typeMappingSource ,
44+ NpgsqlSqlExpressionFactory sqlExpressionFactory )
45+ : IMemberTranslator
4646{
47- private static readonly MemberInfo SystemClock_Instance =
48- typeof ( SystemClock ) . GetRuntimeProperty ( nameof ( SystemClock . Instance ) ) ! ;
49-
50- private static readonly MemberInfo ZonedDateTime_LocalDateTime =
51- typeof ( ZonedDateTime ) . GetRuntimeProperty ( nameof ( ZonedDateTime . LocalDateTime ) ) ! ;
52-
53- private static readonly MemberInfo Interval_Start =
54- typeof ( Interval ) . GetRuntimeProperty ( nameof ( Interval . Start ) ) ! ;
55-
56- private static readonly MemberInfo Interval_End =
57- typeof ( Interval ) . GetRuntimeProperty ( nameof ( Interval . End ) ) ! ;
58-
59- private static readonly MemberInfo Interval_HasStart =
60- typeof ( Interval ) . GetRuntimeProperty ( nameof ( Interval . HasStart ) ) ! ;
61-
62- private static readonly MemberInfo Interval_HasEnd =
63- typeof ( Interval ) . GetRuntimeProperty ( nameof ( Interval . HasEnd ) ) ! ;
64-
65- private static readonly MemberInfo Interval_Duration =
66- typeof ( Interval ) . GetRuntimeProperty ( nameof ( Interval . Duration ) ) ! ;
67-
68- private static readonly MemberInfo DateInterval_Start =
69- typeof ( DateInterval ) . GetRuntimeProperty ( nameof ( DateInterval . Start ) ) ! ;
70-
71- private static readonly MemberInfo DateInterval_End =
72- typeof ( DateInterval ) . GetRuntimeProperty ( nameof ( DateInterval . End ) ) ! ;
73-
74- private static readonly MemberInfo DateInterval_Length =
75- typeof ( DateInterval ) . GetRuntimeProperty ( nameof ( DateInterval . Length ) ) ! ;
76-
77- private static readonly MemberInfo DateTimeZoneProviders_TzDb =
78- typeof ( DateTimeZoneProviders ) . GetRuntimeProperty ( nameof ( DateTimeZoneProviders . Tzdb ) ) ! ;
79-
80- private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory ;
81- private readonly IRelationalTypeMappingSource _typeMappingSource ;
82- private readonly RelationalTypeMapping _dateTypeMapping ;
83- private readonly RelationalTypeMapping _periodTypeMapping ;
84- private readonly RelationalTypeMapping _localDateTimeTypeMapping ;
85-
86- /// <summary>
87- /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
88- /// the same compatibility standards as public APIs. It may be changed or removed without notice in
89- /// any release. You should only use it directly in your code with extreme caution and knowing that
90- /// doing so can result in application failures when updating to a new Entity Framework Core release.
91- /// </summary>
92- public NpgsqlNodaTimeMemberTranslator (
93- IRelationalTypeMappingSource typeMappingSource ,
94- NpgsqlSqlExpressionFactory sqlExpressionFactory )
95- {
96- _typeMappingSource = typeMappingSource ;
97- _sqlExpressionFactory = sqlExpressionFactory ;
98- _dateTypeMapping = typeMappingSource . FindMapping ( typeof ( LocalDate ) ) ! ;
99- _periodTypeMapping = typeMappingSource . FindMapping ( typeof ( Period ) ) ! ;
100- _localDateTimeTypeMapping = typeMappingSource . FindMapping ( typeof ( LocalDateTime ) ) ! ;
101- }
102-
47+ private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory = sqlExpressionFactory ;
48+ private readonly IRelationalTypeMappingSource _typeMappingSource = typeMappingSource ;
49+ private readonly RelationalTypeMapping _dateTypeMapping = typeMappingSource . FindMapping ( typeof ( LocalDate ) ) ! ;
50+ private readonly RelationalTypeMapping _periodTypeMapping = typeMappingSource . FindMapping ( typeof ( Period ) ) ! ;
51+ private readonly RelationalTypeMapping _localDateTimeTypeMapping = typeMappingSource . FindMapping ( typeof ( LocalDateTime ) ) ! ;
10352 private static readonly bool [ ] [ ] TrueArrays = [ [ ] , [ true ] , [ true , true ] ] ;
10453
10554 /// <inheritdoc />
@@ -110,12 +59,12 @@ public NpgsqlNodaTimeMemberTranslator(
11059 IDiagnosticsLogger < DbLoggerCategory . Query > logger )
11160 {
11261 // This is necessary to allow translation of methods on SystemClock.Instance
113- if ( member == SystemClock_Instance )
62+ if ( member . DeclaringType == typeof ( SystemClock ) && member . Name == nameof ( SystemClock . Instance ) )
11463 {
11564 return _sqlExpressionFactory . Constant ( SystemClock . Instance ) ;
11665 }
11766
118- if ( member == DateTimeZoneProviders_TzDb )
67+ if ( member . DeclaringType == typeof ( DateTimeZoneProviders ) && member . Name == nameof ( DateTimeZoneProviders . Tzdb ) )
11968 {
12069 return PendingDateTimeZoneProviderExpression . Instance ;
12170 }
@@ -181,44 +130,34 @@ SqlExpression TranslateDurationTotalMember(SqlExpression instance, double diviso
181130
182131 private SqlExpression ? TranslateInterval ( SqlExpression instance , MemberInfo member )
183132 {
184- if ( member == Interval_Start )
185- {
186- return Lower ( ) ;
187- }
188-
189- if ( member == Interval_End )
190- {
191- return Upper ( ) ;
192- }
193-
194- if ( member == Interval_HasStart )
195- {
196- return _sqlExpressionFactory . Not (
197- _sqlExpressionFactory . Function (
198- "lower_inf" ,
199- [ instance ] ,
200- nullable : true ,
201- argumentsPropagateNullability : TrueArrays [ 1 ] ,
202- typeof ( bool ) ) ) ;
203- }
204-
205- if ( member == Interval_HasEnd )
206- {
207- return _sqlExpressionFactory . Not (
208- _sqlExpressionFactory . Function (
209- "upper_inf" ,
210- [ instance ] ,
211- nullable : true ,
212- argumentsPropagateNullability : TrueArrays [ 1 ] ,
213- typeof ( bool ) ) ) ;
214- }
215-
216- if ( member == Interval_Duration )
133+ return member . Name switch
217134 {
218- return _sqlExpressionFactory . Subtract ( Upper ( ) , Lower ( ) , _typeMappingSource . FindMapping ( typeof ( Duration ) ) ) ;
219- }
135+ nameof ( Interval . Start ) => Lower ( ) ,
136+ nameof ( Interval . End ) => Upper ( ) ,
137+
138+ nameof ( Interval . HasStart )
139+ => _sqlExpressionFactory . Not (
140+ _sqlExpressionFactory . Function (
141+ "lower_inf" ,
142+ [ instance ] ,
143+ nullable : true ,
144+ argumentsPropagateNullability : TrueArrays [ 1 ] ,
145+ typeof ( bool ) ) ) ,
146+
147+ nameof ( Interval . HasEnd )
148+ => _sqlExpressionFactory . Not (
149+ _sqlExpressionFactory . Function (
150+ "upper_inf" ,
151+ [ instance ] ,
152+ nullable : true ,
153+ argumentsPropagateNullability : TrueArrays [ 1 ] ,
154+ typeof ( bool ) ) ) ,
155+
156+ nameof ( Interval . Duration )
157+ => _sqlExpressionFactory . Subtract ( Upper ( ) , Lower ( ) , _typeMappingSource . FindMapping ( typeof ( Duration ) ) ) ,
220158
221- return null ;
159+ _ => null
160+ } ;
222161
223162 SqlExpression Lower ( )
224163 => _sqlExpressionFactory . Function (
@@ -244,28 +183,23 @@ SqlExpression Upper()
244183 // NodaTime DateInterval is inclusive on both ends.
245184 // PostgreSQL daterange is a discrete range type; this means it gets normalized to inclusive lower bound, exclusive upper bound.
246185 // So we can translate Start as-is, but need to subtract a day for End.
247- if ( member == DateInterval_Start )
186+ return member . Name switch
248187 {
249- return Lower ( ) ;
250- }
188+ nameof ( DateInterval . Start ) => Lower ( ) ,
251189
252- if ( member == DateInterval_End )
253- {
254190 // PostgreSQL creates a result of type 'timestamp without time zone' when subtracting intervals from dates, so add a cast back
255191 // to date.
256- return _sqlExpressionFactory . Convert (
257- _sqlExpressionFactory . Subtract (
258- Upper ( ) ,
259- _sqlExpressionFactory . Constant ( Period . FromDays ( 1 ) , _periodTypeMapping ) ) , typeof ( LocalDate ) ,
260- _typeMappingSource . FindMapping ( typeof ( LocalDate ) ) ) ;
261- }
192+ nameof ( DateInterval . End )
193+ => _sqlExpressionFactory . Convert (
194+ _sqlExpressionFactory . Subtract (
195+ Upper ( ) ,
196+ _sqlExpressionFactory . Constant ( Period . FromDays ( 1 ) , _periodTypeMapping ) ) , typeof ( LocalDate ) ,
197+ _typeMappingSource . FindMapping ( typeof ( LocalDate ) ) ) ,
262198
263- if ( member == DateInterval_Length )
264- {
265- return _sqlExpressionFactory . Subtract ( Upper ( ) , Lower ( ) ) ;
266- }
199+ nameof ( DateInterval . Length ) => _sqlExpressionFactory . Subtract ( Upper ( ) , Lower ( ) ) ,
267200
268- return null ;
201+ _ => null
202+ } ;
269203
270204 SqlExpression Lower ( )
271205 => _sqlExpressionFactory . Function (
@@ -378,7 +312,7 @@ private SqlExpression GetDatePartExpressionDouble(
378312 typeof ( LocalDateTime ) ,
379313 _localDateTimeTypeMapping ) ;
380314
381- return member == ZonedDateTime_LocalDateTime
315+ return member . Name == nameof ( ZonedDateTime . LocalDateTime )
382316 ? instance
383317 : TranslateDateTime ( instance , member ) ;
384318 }
@@ -388,7 +322,7 @@ private SqlExpression GetDatePartExpressionDouble(
388322 // The same works also for the LocalDateTime member.
389323 instance = _sqlExpressionFactory . AtUtc ( instance ) ;
390324
391- return member == ZonedDateTime_LocalDateTime
325+ return member . Name == nameof ( ZonedDateTime . LocalDateTime )
392326 ? instance
393327 : TranslateDateTime ( instance , member ) ;
394328 }
0 commit comments