22using System . Collections . Generic ;
33using System . Linq ;
44using System . Text ;
5+ using Microsoft . EntityFrameworkCore . Metadata ;
56using Microsoft . EntityFrameworkCore . Update ;
67
78namespace EntityFrameworkCore . Ydb . Update . Internal ;
@@ -18,9 +19,8 @@ out bool requiresTransaction
1819 var name = command . TableName ;
1920 var schema = command . Schema ;
2021 var operations = command . ColumnModifications ;
21-
22- var writeOperations = operations . Where ( o => o . IsWrite ) . ToList ( ) ;
23- var readOperations = operations . Where ( o => o . IsRead ) . ToList ( ) ;
22+ var writeOperations = operations . Where ( o => o . IsWrite && ! IsStoreGeneratedAndIgnoredBeforeSave ( o ) ) . ToList ( ) ;
23+ var readOperations = operations . Where ( o => o . IsRead || IsStoreGeneratedAndIgnoredBeforeSave ( o ) ) . ToList ( ) ;
2424
2525 AppendInsertCommand (
2626 commandStringBuilder ,
@@ -42,10 +42,9 @@ out bool requiresTransaction
4242 var name = command . TableName ;
4343 var schema = command . Schema ;
4444 var operations = command . ColumnModifications ;
45-
46- var writeOperations = operations . Where ( o => o . IsWrite ) . ToList ( ) ;
45+ var writeOperations = operations . Where ( o => o . IsWrite && ! IsStoreGeneratedAndIgnoredBeforeSave ( o ) ) . ToList ( ) ;
4746 var conditionOperations = operations . Where ( o => o . IsCondition ) . ToList ( ) ;
48- var readOperations = operations . Where ( o => o . IsRead ) . ToList ( ) ;
47+ var readOperations = operations . Where ( o => o . IsRead || IsStoreGeneratedAndIgnoredBeforeSave ( o ) ) . ToList ( ) ;
4948
5049 requiresTransaction = false ;
5150
@@ -105,7 +104,16 @@ protected override void AppendUpdateCommand(
105104 bool appendReturningOneClause = false
106105 )
107106 {
108- AppendUpdateCommandHeader ( commandStringBuilder , name , schema , writeOperations ) ;
107+ var effectiveWrites = writeOperations ;
108+ if ( effectiveWrites . Count == 0 )
109+ {
110+ var noOpColumn = GetNoOpSetColumn ( conditionOperations , readOperations ) ;
111+ AppendUpdateCommandHeader ( commandStringBuilder , name , schema , noOpColumn is null ? effectiveWrites : new [ ] { noOpColumn } ) ;
112+ }
113+ else
114+ {
115+ AppendUpdateCommandHeader ( commandStringBuilder , name , schema , effectiveWrites ) ;
116+ }
109117 AppendWhereClause ( commandStringBuilder , conditionOperations ) ;
110118 AppendReturningClause ( commandStringBuilder , readOperations ) ;
111119 commandStringBuilder . AppendLine ( SqlGenerationHelper . StatementTerminator ) ;
@@ -137,17 +145,12 @@ protected override void AppendReturningClause(
137145 string ? additionalValues = null
138146 )
139147 {
140- if ( operations . Count <= 0 ) return ;
141-
142- commandStringBuilder
143- . AppendLine ( )
144- . Append ( "RETURNING " ) ;
148+ if ( operations . Count <= 0 && string . IsNullOrEmpty ( additionalValues ) ) return ;
145149
146- commandStringBuilder . AppendJoin (
147- ',' ,
148- operations
149- . Select ( operation => SqlGenerationHelper . DelimitIdentifier ( operation . ColumnName ) )
150- ) ;
150+ commandStringBuilder . AppendLine ( ) . Append ( "RETURNING " ) ;
151+ var columns = operations . Select ( o => SqlGenerationHelper . DelimitIdentifier ( o . ColumnName ) ) . ToList ( ) ;
152+ if ( ! string . IsNullOrEmpty ( additionalValues ) ) columns . Add ( additionalValues ! ) ;
153+ commandStringBuilder . AppendJoin ( ',' , columns ) ;
151154 }
152155
153156 public override string GenerateNextSequenceValueOperation ( string name , string ? schema )
@@ -163,4 +166,21 @@ public override string GenerateObtainNextSequenceValueOperation(string name, str
163166 public override void AppendObtainNextSequenceValueOperation (
164167 StringBuilder commandStringBuilder , string name , string ? schema
165168 ) => throw new NotSupportedException ( "Iterating over serial is not supported in YDB" ) ;
169+
170+ private static bool IsStoreGeneratedAndIgnoredBeforeSave ( IColumnModification op )
171+ {
172+ var p = op . Property ;
173+ if ( p == null ) return false ;
174+ if ( p . ValueGenerated != ValueGenerated . OnAdd && p . ValueGenerated != ValueGenerated . OnAddOrUpdate ) return false ;
175+ return p . GetBeforeSaveBehavior ( ) == PropertySaveBehavior . Ignore ;
176+ }
177+
178+ private static IColumnModification ? GetNoOpSetColumn (
179+ IReadOnlyList < IColumnModification > conditionOperations ,
180+ IReadOnlyList < IColumnModification > readOperations
181+ )
182+ {
183+ var candidate = conditionOperations . FirstOrDefault ( ) ?? readOperations . FirstOrDefault ( ) ;
184+ return candidate ;
185+ }
166186}
0 commit comments