1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
+ using Microsoft . EntityFrameworkCore . SqlServer . Internal ;
4
5
using Microsoft . EntityFrameworkCore . SqlServer . Metadata . Internal ;
5
6
6
7
// ReSharper disable once CheckNamespace
@@ -18,6 +19,8 @@ public static class SqlServerEntityTypeExtensions
18
19
{
19
20
private const string DefaultHistoryTableNameSuffix = "History" ;
20
21
22
+ #region Memory-optimized table
23
+
21
24
/// <summary>
22
25
/// Returns a value indicating whether the entity type is mapped to a memory-optimized table.
23
26
/// </summary>
@@ -58,6 +61,10 @@ public static void SetIsMemoryOptimized(this IMutableEntityType entityType, bool
58
61
public static ConfigurationSource ? GetIsMemoryOptimizedConfigurationSource ( this IConventionEntityType entityType )
59
62
=> entityType . FindAnnotation ( SqlServerAnnotationNames . MemoryOptimized ) ? . GetConfigurationSource ( ) ;
60
63
64
+ #endregion Memory-optimized table
65
+
66
+ #region Temporal table
67
+
61
68
/// <summary>
62
69
/// Returns a value indicating whether the entity type is mapped to a temporal table.
63
70
/// </summary>
@@ -271,4 +278,149 @@ public static void SetHistoryTableSchema(this IMutableEntityType entityType, str
271
278
/// <returns>The configuration source for the temporal history table schema setting.</returns>
272
279
public static ConfigurationSource ? GetHistoryTableSchemaConfigurationSource ( this IConventionEntityType entityType )
273
280
=> entityType . FindAnnotation ( SqlServerAnnotationNames . TemporalHistoryTableSchema ) ? . GetConfigurationSource ( ) ;
281
+
282
+ #endregion Temporal table
283
+
284
+ #region SQL OUTPUT clause
285
+
286
+ /// <summary>
287
+ /// Returns a value indicating whether to use the SQL OUTPUT clause when saving changes to the table.
288
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
289
+ /// </summary>
290
+ /// <param name="entityType">The entity type.</param>
291
+ /// <returns><see langword="true" /> if the SQL OUTPUT clause is used to save changes to the table.</returns>
292
+ public static bool IsSqlOutputClauseUsed ( this IReadOnlyEntityType entityType )
293
+ {
294
+ if ( entityType . FindAnnotation ( SqlServerAnnotationNames . UseSqlOutputClause ) is { Value : bool useSqlOutputClause } )
295
+ {
296
+ return useSqlOutputClause ;
297
+ }
298
+
299
+ if ( entityType . FindOwnership ( ) is { } ownership
300
+ && StoreObjectIdentifier . Create ( entityType , StoreObjectType . Table ) is { } tableIdentifier
301
+ && ownership . FindSharedObjectRootForeignKey ( tableIdentifier ) is { } rootForeignKey )
302
+ {
303
+ return rootForeignKey . PrincipalEntityType . IsSqlOutputClauseUsed ( ) ;
304
+ }
305
+
306
+ if ( entityType . BaseType is not null && entityType . GetMappingStrategy ( ) == RelationalAnnotationNames . TphMappingStrategy )
307
+ {
308
+ return entityType . GetRootType ( ) . IsSqlOutputClauseUsed ( ) ;
309
+ }
310
+
311
+ return true ;
312
+ }
313
+
314
+ /// <summary>
315
+ /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table.
316
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
317
+ /// </summary>
318
+ /// <param name="entityType">The entity type.</param>
319
+ /// <param name="useSqlOutputClause">The value to set.</param>
320
+ public static void UseSqlOutputClause ( this IMutableEntityType entityType , bool ? useSqlOutputClause )
321
+ => entityType . SetOrRemoveAnnotation ( SqlServerAnnotationNames . UseSqlOutputClause , useSqlOutputClause ) ;
322
+
323
+ /// <summary>
324
+ /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table.
325
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
326
+ /// </summary>
327
+ /// <param name="entityType">The entity type.</param>
328
+ /// <param name="useSqlOutputClause">The value to set.</param>
329
+ /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
330
+ /// <returns>The configured value.</returns>
331
+ public static bool ? UseSqlOutputClause (
332
+ this IConventionEntityType entityType ,
333
+ bool ? useSqlOutputClause ,
334
+ bool fromDataAnnotation = false )
335
+ => ( bool ? ) entityType . SetOrRemoveAnnotation (
336
+ SqlServerAnnotationNames . UseSqlOutputClause ,
337
+ useSqlOutputClause ,
338
+ fromDataAnnotation ) ? . Value ;
339
+
340
+ /// <summary>
341
+ /// Gets the configuration source for whether to use the SQL OUTPUT clause when saving changes to the table.
342
+ /// </summary>
343
+ /// <param name="entityType">The entity type.</param>
344
+ /// <returns>The configuration source for the memory-optimized setting.</returns>
345
+ public static ConfigurationSource ? GetUseSqlOutputClauseConfigurationSource ( this IConventionEntityType entityType )
346
+ => entityType . FindAnnotation ( SqlServerAnnotationNames . UseSqlOutputClause ) ? . GetConfigurationSource ( ) ;
347
+
348
+ /// <summary>
349
+ /// Returns a value indicating whether to use the SQL OUTPUT clause when saving changes to the specified table.
350
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
351
+ /// </summary>
352
+ /// <param name="entityType">The entity type.</param>
353
+ /// <param name="storeObject">The identifier of the table-like store object.</param>
354
+ /// <returns>A value indicating whether the SQL OUTPUT clause is used to save changes to the associated table.</returns>
355
+ public static bool IsSqlOutputClauseUsed ( this IReadOnlyEntityType entityType , in StoreObjectIdentifier storeObject )
356
+ {
357
+ if ( entityType . FindMappingFragment ( storeObject ) is { } overrides
358
+ && overrides . FindAnnotation ( SqlServerAnnotationNames . UseSqlOutputClause ) is { Value : bool useSqlOutputClause } )
359
+ {
360
+ return useSqlOutputClause ;
361
+ }
362
+
363
+ if ( StoreObjectIdentifier . Create ( entityType , storeObject . StoreObjectType ) == storeObject )
364
+ {
365
+ return entityType . IsSqlOutputClauseUsed ( ) ;
366
+ }
367
+
368
+ if ( entityType . FindOwnership ( ) is { } ownership
369
+ && ownership . FindSharedObjectRootForeignKey ( storeObject ) is { } rootForeignKey )
370
+ {
371
+ return rootForeignKey . PrincipalEntityType . IsSqlOutputClauseUsed ( storeObject ) ;
372
+ }
373
+
374
+ if ( entityType . BaseType is not null && entityType . GetMappingStrategy ( ) == RelationalAnnotationNames . TphMappingStrategy )
375
+ {
376
+ return entityType . GetRootType ( ) . IsSqlOutputClauseUsed ( storeObject ) ;
377
+ }
378
+
379
+ return true ;
380
+ }
381
+
382
+ /// <summary>
383
+ /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table.
384
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
385
+ /// </summary>
386
+ /// <param name="entityType">The entity type.</param>
387
+ /// <param name="useSqlOutputClause">The value to set.</param>
388
+ /// <param name="storeObject">The identifier of the table-like store object.</param>
389
+ public static void UseSqlOutputClause (
390
+ this IMutableEntityType entityType ,
391
+ bool ? useSqlOutputClause ,
392
+ in StoreObjectIdentifier storeObject )
393
+ {
394
+ if ( StoreObjectIdentifier . Create ( entityType , storeObject . StoreObjectType ) == storeObject )
395
+ {
396
+ entityType . UseSqlOutputClause ( useSqlOutputClause ) ;
397
+ return ;
398
+ }
399
+
400
+ entityType
401
+ . GetOrCreateMappingFragment ( storeObject )
402
+ . UseSqlOutputClause ( useSqlOutputClause ) ;
403
+ }
404
+
405
+ /// <summary>
406
+ /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table.
407
+ /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers.
408
+ /// </summary>
409
+ /// <param name="entityType">The entity type.</param>
410
+ /// <param name="useSqlOutputClause">The value to set.</param>
411
+ /// <param name="storeObject">The identifier of the table-like store object.</param>
412
+ /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
413
+ /// <returns>The configured value.</returns>
414
+ public static bool ? UseSqlOutputClause (
415
+ this IConventionEntityType entityType ,
416
+ bool ? useSqlOutputClause ,
417
+ in StoreObjectIdentifier storeObject ,
418
+ bool fromDataAnnotation = false )
419
+ => StoreObjectIdentifier . Create ( entityType , storeObject . StoreObjectType ) == storeObject
420
+ ? entityType . UseSqlOutputClause ( useSqlOutputClause , fromDataAnnotation )
421
+ : entityType
422
+ . GetOrCreateMappingFragment ( storeObject , fromDataAnnotation )
423
+ . UseSqlOutputClause ( useSqlOutputClause , fromDataAnnotation ) ;
424
+
425
+ #endregion SQL OUTPUT clause
274
426
}
0 commit comments