Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[automated] Merge branch 'release/8.0' => 'main' #31880

Merged
1 commit merged into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/EFCore/ChangeTracking/Internal/IdentityMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,13 @@ protected virtual void Remove(TKey key, InternalEntityEntry entry)

if (otherEntry == null)
{
if (_identityMap.TryGetValue(key, out var existingEntry)
&& existingEntry == entry)
if (!_identityMap.TryGetValue(key, out var existingEntry)
|| existingEntry != entry)
{
_identityMap.Remove(key);
return;
}

_identityMap.Remove(key);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore/ChangeTracking/Internal/NavigationFixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,9 +1098,11 @@ private void FindOrCreateJoinEntry(

SetForeignKeyProperties(
joinEntry, arguments.Entry, arguments.SkipNavigation.ForeignKey, arguments.SetModified, arguments.FromQuery);
SetNavigation(joinEntry, arguments.SkipNavigation.ForeignKey.DependentToPrincipal, arguments.Entry, arguments.FromQuery);
SetForeignKeyProperties(
joinEntry, arguments.OtherEntry, arguments.SkipNavigation.Inverse.ForeignKey, arguments.SetModified,
arguments.FromQuery);
SetNavigation(joinEntry, arguments.SkipNavigation.Inverse.ForeignKey.DependentToPrincipal, arguments.OtherEntry, arguments.FromQuery);

joinEntry.SetEntityState(
arguments.SetModified
Expand Down
94 changes: 76 additions & 18 deletions test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -856,82 +856,97 @@ public void Can_replace_identifying_FK_entity_with_many_to_many()
[ConditionalTheory]
[MemberData(
nameof(DataGenerator.GetCombinations),
new object[] { 0, 1, 2, 3, 4 },
new object[] { 0, 1, 2, 3, 4, 7 },
2,
MemberType = typeof(DataGenerator))]
public void Can_insert_entities_with_generated_PKs(int studentCount, int courseCount)
{
var students = new[]
var students = new Student[]
{
new()
{
FirstMidName = "Carson",
LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2019-09-01")
},
new Student
new()
{
FirstMidName = "Meredith",
LastName = "Alonso",
EnrollmentDate = DateTime.Parse("2017-09-01")
},
new Student
new()
{
FirstMidName = "Arturo",
LastName = "Anand",
EnrollmentDate = DateTime.Parse("2018-09-01")
},
new Student
new()
{
FirstMidName = "Gytis",
LastName = "Barzdukas",
EnrollmentDate = DateTime.Parse("2017-09-01")
},
new Student
new()
{
FirstMidName = "Yan",
LastName = "Li",
EnrollmentDate = DateTime.Parse("2017-09-01")
},
new Student
new()
{
FirstMidName = "Peggy",
LastName = "Justice",
EnrollmentDate = DateTime.Parse("2016-09-01")
},
new Student
new()
{
FirstMidName = "Laura",
LastName = "Norman",
EnrollmentDate = DateTime.Parse("2018-09-01")
},
new Student
new()
{
FirstMidName = "Nino",
LastName = "Olivetto",
EnrollmentDate = DateTime.Parse("2019-09-01")
}
};

var courses = new[]
var courses = new Course[]
{
new() { Title = "Chemistry", Credits = 3 },
new Course { Title = "Microeconomics", Credits = 3 },
new Course { Title = "Macroeconomics", Credits = 3 },
new Course { Title = "Calculus", Credits = 4 },
new Course { Title = "Trigonometry", Credits = 4 },
new Course { Title = "Composition", Credits = 3 },
new Course { Title = "Literature", Credits = 4 }
new() { Title = "Microeconomics", Credits = 3 },
new() { Title = "Macroeconomics", Credits = 3 },
new() { Title = "Calculus", Credits = 4 },
new() { Title = "Trigonometry", Credits = 4 },
new() { Title = "Composition", Credits = 3 },
new() { Title = "Literature", Credits = 4 }
};

using var testDatabase = SqlServerTestStore.CreateInitialized(DatabaseName);
var options = Fixture.CreateOptions(testDatabase);

var nextCourse = 0;
using (var context = new UniversityContext(options))
{
context.Database.EnsureCreatedResiliently();
for (var i = 0; i < studentCount; i++)
{
if (courseCount > 1)
{
students[i].Courses.Add(courses[nextCourse++]);
if(nextCourse >= courseCount)
{
nextCourse = 0;
}

students[i].Courses.Add(courses[nextCourse++]);
if (nextCourse >= courseCount)
{
nextCourse = 0;
}
}
context.Students.Add(students[i]);
}

Expand All @@ -940,13 +955,48 @@ public void Can_insert_entities_with_generated_PKs(int studentCount, int courseC
context.Courses.Add(courses[i]);
}

Assert.All(context.Enrollments.Local, e =>
{
var entry = context.Entry(e);
var student = e.Student;
var course = e.Course;
Assert.Equal(student.Id, e.StudentId);
Assert.Equal(course.Id, e.CourseId);
Assert.Equal(context.Entry(student).Property(e => e.Id).CurrentValue, entry.Property(e => e.StudentId).CurrentValue);
Assert.Equal(context.Entry(course).Property(e => e.Id).CurrentValue, entry.Property(e => e.CourseId).CurrentValue);
Assert.True(entry.Property(e => e.StudentId).IsTemporary);
Assert.True(entry.Property(e => e.CourseId).IsTemporary);
Assert.True(context.Entry(student).Property(e => e.Id).IsTemporary);
Assert.True(context.Entry(course).Property(e => e.Id).IsTemporary);
});

context.SaveChanges();

Assert.All(context.Enrollments.Local, e =>
{
var entry = context.Entry(e);
var student = e.Student;
var course = e.Course;
Assert.Equal(student.Id, e.StudentId);
Assert.Equal(course.Id, e.CourseId);
Assert.False(entry.Property(e => e.StudentId).IsTemporary);
Assert.False(entry.Property(e => e.CourseId).IsTemporary);
});
}

using (var context = new UniversityContext(options))
{
Assert.Equal(studentCount, context.Students.Count());
Assert.Equal(courseCount, context.Courses.Count());
Assert.Equal(studentCount, context.Students.ToList().Count());
Assert.Equal(courseCount, context.Courses.ToList().Count());

var enrollments = context.Enrollments.Include(e => e.Course).Include(e => e.Student).ToList();
Assert.All(enrollments, e =>
{
var student = e.Student;
var course = e.Course;
Assert.Equal(student.Id, e.StudentId);
Assert.Equal(course.Id, e.CourseId);
});
}
}

Expand All @@ -960,6 +1010,8 @@ public class Course

public virtual ICollection<Enrollment> Enrollments { get; set; } = new List<Enrollment>();

public virtual ICollection<Student> Students { get; set; } = new List<Student>();

public byte[] RowVersion { get; set; } = Array.Empty<byte>();
}

Expand All @@ -975,6 +1027,8 @@ public class Student

public virtual ICollection<Enrollment> Enrollments { get; } = new List<Enrollment>();

public virtual ICollection<Course> Courses { get; set; } = new List<Course>();

public byte[] RowVersion { get; set; } = Array.Empty<byte>();
}

Expand Down Expand Up @@ -1030,6 +1084,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)

builder.Property(x => x.RowVersion)
.IsRowVersion();

builder.HasMany(x => x.Students)
.WithMany(x => x.Courses)
.UsingEntity<Enrollment>();
});

modelBuilder.Entity<Student>(
Expand Down
Loading