Skip to content

Commit d994045

Browse files
authored
Refactor InternalEntityEntry (#36165)
Part of #31237
1 parent afda113 commit d994045

File tree

222 files changed

+8164
-7617
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

222 files changed

+8164
-7617
lines changed

.github/copilot-instructions.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ If you are not sure, do not guess, just tell that you don't know or ask clarifyi
8686

8787
- Follow the existing test patterns in the corresponding test projects
8888
- Create both unit tests and functional tests where appropriate
89-
- Add or modify `SQL` and `C#` baselines for tests when necessary
90-
- When running the tests specify the test project and let it be rebuilt.
89+
- Fix `SQL` and `C#` baselines for tests when necessary by setting the `EF_TEST_REWRITE_BASELINES` env var to `1`
90+
- Before building or running the tests execute `restore.cmd` or `restore.sh` and `activate.ps1` or `activate.sh` to set up the environment
91+
- When running the tests specify the test project and let it be rebuilt by not adding `--no-build`
9192

9293
## Documentation
9394

src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
77
using Microsoft.EntityFrameworkCore.Design.Internal;
88
using Microsoft.EntityFrameworkCore.Internal;
9-
using Microsoft.EntityFrameworkCore.Metadata;
109
using Microsoft.EntityFrameworkCore.Metadata.Internal;
1110
using Microsoft.EntityFrameworkCore.Query.Internal;
1211

@@ -1498,8 +1497,10 @@ private void
14981497
var variableName = parameters.TargetName;
14991498
var mainBuilder = parameters.MainBuilder;
15001499
var unsafeAccessors = new HashSet<string>();
1500+
var isOnComplexCollection = property.DeclaringType is IReadOnlyComplexType complexType && complexType.ComplexProperty.IsCollection;
15011501

15021502
if (!property.IsShadowProperty()
1503+
&& !isOnComplexCollection
15031504
&& property is not IServiceProperty) // Service properties don't use property accessors
15041505
{
15051506
ClrPropertyGetterFactory.Instance.Create(
@@ -1559,7 +1560,8 @@ private void
15591560
.DecrementIndent();
15601561
}
15611562

1562-
if (property is not IServiceProperty)
1563+
if (property is not IServiceProperty
1564+
&& !isOnComplexCollection)
15631565
{
15641566
PropertyAccessorsFactory.Instance.Create(
15651567
property,
@@ -2783,6 +2785,21 @@ private void CreateAnnotations(
27832785
mainBuilder.AppendLine(";");
27842786
}
27852787

2788+
foreach (var navigation in entityType.GetSkipNavigations())
2789+
{
2790+
var variableName = _code.Identifier(navigation.Name, navigation, parameters.ScopeObjects, capitalize: false);
2791+
2792+
mainBuilder
2793+
.Append($"var {variableName} = ")
2794+
.Append($"{parameters.TargetName}.FindSkipNavigation({_code.Literal(navigation.Name)})");
2795+
if (nullable)
2796+
{
2797+
mainBuilder.Append("!");
2798+
}
2799+
2800+
mainBuilder.AppendLine(";");
2801+
}
2802+
27862803
var runtimeType = (IRuntimeEntityType)entityType;
27872804
var unsafeAccessors = new HashSet<string>();
27882805

@@ -2859,17 +2876,18 @@ private void CreateAnnotations(
28592876
.DecrementIndent();
28602877

28612878
AddNamespace(typeof(PropertyCounts), parameters.Namespaces);
2862-
var counts = runtimeType.Counts;
2879+
var counts = runtimeType.CalculateCounts();
28632880
mainBuilder
2864-
.Append(parameters.TargetName).AppendLine(".Counts = new PropertyCounts(")
2881+
.Append(parameters.TargetName).AppendLine(".SetCounts(new PropertyCounts(")
28652882
.IncrementIndent()
28662883
.Append("propertyCount: ").Append(_code.Literal(counts.PropertyCount)).AppendLine(",")
28672884
.Append("navigationCount: ").Append(_code.Literal(counts.NavigationCount)).AppendLine(",")
28682885
.Append("complexPropertyCount: ").Append(_code.Literal(counts.ComplexPropertyCount)).AppendLine(",")
2886+
.Append("complexCollectionCount: ").Append(_code.Literal(counts.ComplexCollectionCount)).AppendLine(",")
28692887
.Append("originalValueCount: ").Append(_code.Literal(counts.OriginalValueCount)).AppendLine(",")
28702888
.Append("shadowCount: ").Append(_code.Literal(counts.ShadowCount)).AppendLine(",")
28712889
.Append("relationshipCount: ").Append(_code.Literal(counts.RelationshipCount)).AppendLine(",")
2872-
.Append("storeGeneratedCount: ").Append(_code.Literal(counts.StoreGeneratedCount)).AppendLine(");")
2890+
.Append("storeGeneratedCount: ").Append(_code.Literal(counts.StoreGeneratedCount)).AppendLine("));")
28732891
.DecrementIndent();
28742892

28752893
Check.DebugAssert(

src/EFCore.Relational/Metadata/Internal/RelationalModel.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Reflection.Metadata;
54
using System.Text;
6-
using System.Text.Json;
75

86
namespace Microsoft.EntityFrameworkCore.Metadata.Internal;
97

@@ -282,7 +280,7 @@ private static void AddDefaultMappings(
282280
principalRootEntityType = ownership.PrincipalEntityType;
283281
}
284282

285-
if (principalRootEntityType.FindDiscriminatorProperty() is not null) // tph
283+
if (principalRootEntityType.FindDiscriminatorProperty() is not null)
286284
{
287285
principalRootEntityType = principalRootEntityType.GetRootType();
288286
}

src/EFCore/ChangeTracking/CollectionEntry.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ public override bool IsModified
109109

110110
if (Metadata is ISkipNavigation skipNavigation)
111111
{
112-
if (InternalEntry.EntityState != EntityState.Unchanged
113-
&& InternalEntry.EntityState != EntityState.Detached)
112+
if (InternalEntityEntry.EntityState is not EntityState.Unchanged and not EntityState.Detached)
114113
{
115114
return true;
116115
}
@@ -122,11 +121,11 @@ public override bool IsModified
122121
{
123122
if (joinEntry.EntityType == joinEntityType
124123
&& stateManager.FindPrincipal(joinEntry, foreignKey) == InternalEntry
125-
&& (joinEntry.EntityState == EntityState.Added
126-
|| joinEntry.EntityState == EntityState.Deleted
124+
&& (joinEntry.EntityState is EntityState.Added
125+
|| joinEntry.EntityState is EntityState.Deleted
127126
|| foreignKey.Properties.Any(joinEntry.IsModified)
128127
|| inverseForeignKey.Properties.Any(joinEntry.IsModified)
129-
|| (stateManager.FindPrincipal(joinEntry, inverseForeignKey)?.EntityState == EntityState.Deleted)))
128+
|| (stateManager.FindPrincipal(joinEntry, inverseForeignKey)?.EntityState is EntityState.Deleted)))
130129
{
131130
return true;
132131
}
@@ -231,7 +230,7 @@ public override void Load(LoadOptions options)
231230

232231
if (!IsLoaded)
233232
{
234-
TargetLoader.Load(InternalEntry, options);
233+
TargetLoader.Load(InternalEntityEntry, options);
235234
}
236235
}
237236

@@ -279,7 +278,7 @@ public override Task LoadAsync(LoadOptions options, CancellationToken cancellati
279278

280279
return IsLoaded
281280
? Task.CompletedTask
282-
: TargetLoader.LoadAsync(InternalEntry, options, cancellationToken);
281+
: TargetLoader.LoadAsync(InternalEntityEntry, options, cancellationToken);
283282
}
284283

285284
/// <summary>
@@ -300,11 +299,11 @@ public override IQueryable Query()
300299
{
301300
EnsureInitialized();
302301

303-
return TargetLoader.Query(InternalEntry);
302+
return TargetLoader.Query(InternalEntityEntry);
304303
}
305304

306305
private void EnsureInitialized()
307-
=> InternalEntry.GetOrCreateCollection(Metadata, forMaterialization: true);
306+
=> InternalEntityEntry.GetOrCreateCollection(Metadata, forMaterialization: true);
308307

309308
/// <summary>
310309
/// The <see cref="EntityEntry" /> of an entity this navigation targets.
@@ -332,7 +331,7 @@ private void EnsureInitialized()
332331
[EntityFrameworkInternal]
333332
protected virtual InternalEntityEntry? GetInternalTargetEntry(object entity)
334333
=> CurrentValue == null
335-
|| !InternalEntry.CollectionContains(Metadata, entity)
334+
|| !InternalEntityEntry.CollectionContains(Metadata, entity)
336335
? null
337336
: InternalEntry.StateManager.GetOrCreateEntry(entity, Metadata.TargetEntityType);
338337

src/EFCore/ChangeTracking/CollectionEntry`.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public CollectionEntry(InternalEntityEntry internalEntry, INavigationBase naviga
5959
/// </remarks>
6060
/// <value> An entry for the entity that owns this member. </value>
6161
public new virtual EntityEntry<TEntity> EntityEntry
62-
=> new(InternalEntry);
62+
=> new(InternalEntityEntry);
6363

6464
/// <summary>
6565
/// Gets or sets the value currently assigned to this property. If the current value is set using this property,
@@ -73,7 +73,7 @@ public CollectionEntry(InternalEntityEntry internalEntry, INavigationBase naviga
7373
/// </remarks>
7474
public new virtual IEnumerable<TRelatedEntity>? CurrentValue
7575
{
76-
get => (IEnumerable<TRelatedEntity>?)this.GetInfrastructure().GetCurrentValue(Metadata);
76+
get => (IEnumerable<TRelatedEntity>?)InternalEntry.GetCurrentValue(Metadata);
7777
set => base.CurrentValue = value;
7878
}
7979

@@ -93,7 +93,7 @@ public CollectionEntry(InternalEntityEntry internalEntry, INavigationBase naviga
9393
/// </remarks>
9494
public new virtual IQueryable<TRelatedEntity> Query()
9595
{
96-
InternalEntry.GetOrCreateCollection(Metadata, forMaterialization: true);
96+
InternalEntityEntry.GetOrCreateCollection(Metadata, forMaterialization: true);
9797

9898
return (IQueryable<TRelatedEntity>)base.Query();
9999
}

src/EFCore/ChangeTracking/ComplexPropertyEntry.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class ComplexPropertyEntry : MemberEntry
2828
/// doing so can result in application failures when updating to a new Entity Framework Core release.
2929
/// </summary>
3030
[EntityFrameworkInternal]
31-
public ComplexPropertyEntry(InternalEntityEntry internalEntry, IComplexProperty complexProperty)
31+
public ComplexPropertyEntry(IInternalEntry internalEntry, IComplexProperty complexProperty)
3232
: base(internalEntry, complexProperty)
3333
{
3434
}
@@ -48,7 +48,7 @@ public ComplexPropertyEntry(InternalEntityEntry internalEntry, IComplexProperty
4848
/// </remarks>
4949
public override bool IsModified
5050
{
51-
get => Metadata.ComplexType.GetFlattenedProperties().Any(property => InternalEntry.IsModified(property));
51+
get => Metadata.ComplexType.GetFlattenedProperties().Any(InternalEntry.IsModified);
5252
set
5353
{
5454
foreach (var property in Metadata.ComplexType.GetFlattenedProperties())

src/EFCore/ChangeTracking/ComplexPropertyEntry`.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class ComplexPropertyEntry<TEntity, TComplexProperty> : ComplexPropertyEn
3131
/// doing so can result in application failures when updating to a new Entity Framework Core release.
3232
/// </summary>
3333
[EntityFrameworkInternal]
34-
public ComplexPropertyEntry(InternalEntityEntry internalEntry, IComplexProperty complexProperty)
34+
public ComplexPropertyEntry(IInternalEntry internalEntry, IComplexProperty complexProperty)
3535
: base(internalEntry, complexProperty)
3636
{
3737
}
@@ -45,7 +45,7 @@ public ComplexPropertyEntry(InternalEntityEntry internalEntry, IComplexProperty
4545
/// examples.
4646
/// </remarks>
4747
public new virtual EntityEntry<TEntity> EntityEntry
48-
=> new(InternalEntry);
48+
=> new(InternalEntry.EntityEntry);
4949

5050
/// <summary>
5151
/// Gets or sets the value currently assigned to this property. If the current value is set using this property,

0 commit comments

Comments
 (0)