@@ -33,6 +33,10 @@ public class ValueGenerationManager : IValueGenerationManager
33
33
private readonly IKeyPropagator _keyPropagator ;
34
34
private readonly IDiagnosticsLogger < DbLoggerCategory . ChangeTracking > _logger ;
35
35
private readonly ILoggingOptions _loggingOptions ;
36
+ private readonly Dictionary < IEntityType , List < IProperty > > _entityTypePropagatingPropertiesMap
37
+ = new Dictionary < IEntityType , List < IProperty > > ( ) ;
38
+ private readonly Dictionary < IEntityType , List < IProperty > > _entityTypeGeneratingPropertiesMap
39
+ = new Dictionary < IEntityType , List < IProperty > > ( ) ;
36
40
37
41
/// <summary>
38
42
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -61,8 +65,13 @@ public ValueGenerationManager(
61
65
public virtual InternalEntityEntry Propagate ( InternalEntityEntry entry )
62
66
{
63
67
InternalEntityEntry chosenPrincipal = null ;
64
- foreach ( var property in FindPropagatingProperties ( entry ) )
68
+ foreach ( var property in FindCandidatePropagatingProperties ( entry ) )
65
69
{
70
+ if ( ! entry . HasDefaultValue ( property ) )
71
+ {
72
+ continue ;
73
+ }
74
+
66
75
var principalEntry = _keyPropagator . PropagateValue ( entry , property ) ;
67
76
if ( chosenPrincipal == null )
68
77
{
@@ -79,12 +88,19 @@ public virtual InternalEntityEntry Propagate(InternalEntityEntry entry)
79
88
/// any release. You should only use it directly in your code with extreme caution and knowing that
80
89
/// doing so can result in application failures when updating to a new Entity Framework Core release.
81
90
/// </summary>
82
- public virtual void Generate ( InternalEntityEntry entry , bool includePKs = true )
91
+ public virtual void Generate ( InternalEntityEntry entry , bool includePrimaryKey = true )
83
92
{
84
93
var entityEntry = new EntityEntry ( entry ) ;
85
94
86
- foreach ( var property in FindGeneratingProperties ( entry , includePKs ) )
95
+ foreach ( var property in FindCandidateGeneratingProperties ( entry ) )
87
96
{
97
+ if ( ! entry . HasDefaultValue ( property )
98
+ || ( ! includePrimaryKey
99
+ && property . IsPrimaryKey ( ) ) )
100
+ {
101
+ continue ;
102
+ }
103
+
88
104
var valueGenerator = GetValueGenerator ( entry , property ) ;
89
105
90
106
var generatedValue = valueGenerator . Next ( entityEntry ) ;
@@ -120,13 +136,20 @@ private void Log(InternalEntityEntry entry, IProperty property, object generated
120
136
/// </summary>
121
137
public virtual async Task GenerateAsync (
122
138
InternalEntityEntry entry ,
123
- bool includePKs = true ,
139
+ bool includePrimaryKey = true ,
124
140
CancellationToken cancellationToken = default )
125
141
{
126
142
var entityEntry = new EntityEntry ( entry ) ;
127
143
128
- foreach ( var property in FindGeneratingProperties ( entry , includePKs ) )
144
+ foreach ( var property in FindCandidateGeneratingProperties ( entry ) )
129
145
{
146
+ if ( ! entry . HasDefaultValue ( property )
147
+ || ( ! includePrimaryKey
148
+ && property . IsPrimaryKey ( ) ) )
149
+ {
150
+ continue ;
151
+ }
152
+
130
153
var valueGenerator = GetValueGenerator ( entry , property ) ;
131
154
var generatedValue = await valueGenerator . NextAsync ( entityEntry , cancellationToken )
132
155
. ConfigureAwait ( false ) ;
@@ -142,30 +165,42 @@ public virtual async Task GenerateAsync(
142
165
}
143
166
}
144
167
145
- private static IEnumerable < IProperty > FindPropagatingProperties ( InternalEntityEntry entry )
168
+ private List < IProperty > FindCandidatePropagatingProperties ( InternalEntityEntry entry )
146
169
{
147
- foreach ( var property in ( ( EntityType ) entry . EntityType ) . GetProperties ( ) )
170
+ if ( ! _entityTypePropagatingPropertiesMap . TryGetValue ( entry . EntityType , out var candidateProperties ) )
148
171
{
149
- if ( property . IsForeignKey ( )
150
- && entry . HasDefaultValue ( property ) )
172
+ candidateProperties = new List < IProperty > ( ) ;
173
+ foreach ( var property in entry . EntityType . GetProperties ( ) )
151
174
{
152
- yield return property ;
175
+ if ( property . IsForeignKey ( ) )
176
+ {
177
+ candidateProperties . Add ( property ) ;
178
+ }
153
179
}
180
+
181
+ _entityTypePropagatingPropertiesMap [ entry . EntityType ] = candidateProperties ;
154
182
}
183
+
184
+ return candidateProperties ;
155
185
}
156
186
157
- private static IEnumerable < IProperty > FindGeneratingProperties ( InternalEntityEntry entry , bool includePKs = true )
187
+ private List < IProperty > FindCandidateGeneratingProperties ( InternalEntityEntry entry )
158
188
{
159
- foreach ( var property in ( ( EntityType ) entry . EntityType ) . GetProperties ( ) )
189
+ if ( ! _entityTypeGeneratingPropertiesMap . TryGetValue ( entry . EntityType , out var candidateProperties ) )
160
190
{
161
- if ( property . RequiresValueGenerator ( )
162
- && entry . HasDefaultValue ( property )
163
- && ( includePKs
164
- || ! property . IsPrimaryKey ( ) ) )
191
+ candidateProperties = new List < IProperty > ( ) ;
192
+ foreach ( var property in entry . EntityType . GetProperties ( ) )
165
193
{
166
- yield return property ;
194
+ if ( property . RequiresValueGenerator ( ) )
195
+ {
196
+ candidateProperties . Add ( property ) ;
197
+ }
167
198
}
199
+
200
+ _entityTypeGeneratingPropertiesMap [ entry . EntityType ] = candidateProperties ;
168
201
}
202
+
203
+ return candidateProperties ;
169
204
}
170
205
171
206
private ValueGenerator GetValueGenerator ( InternalEntityEntry entry , IProperty property )
0 commit comments