Skip to content

Commit

Permalink
Use a unique identifier for variables during insert
Browse files Browse the repository at this point in the history
FIxes #26632
  • Loading branch information
AndriySvyryd committed Nov 14, 2021
1 parent b38c269 commit f22054d
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 2 deletions.
2 changes: 1 addition & 1 deletion All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31521.260
MinimumVisualStudioVersion = 16.0.28418.106
MinimumVisualStudioVersion = 17.0.31521.260
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B9E4CC99-199C-4E3B-9EC5-D1FDFCD6C27B}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public virtual ResultSetMapping AppendBulkInsertOperation(
modificationCommands[0],
modificationCommands[0].ColumnModifications.Where(o => o.IsKey).ToList(),
modificationCommands[0].ColumnModifications.Where(o => o.IsRead).ToList(),
0);
commandPosition);
}

var readOperations = modificationCommands[0].ColumnModifications.Where(o => o.IsRead).ToList();
Expand Down
188 changes: 188 additions & 0 deletions test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;

Expand Down Expand Up @@ -873,6 +874,193 @@ public void Can_replace_identifying_FK_entity_with_many_to_many()
}
}

[ConditionalTheory]
[MemberData(
nameof(DataGenerator.GetCombinations),
new object[] { 0, 1, 2, 3, 4 },
2,
MemberType = typeof(DataGenerator))]
public void Can_insert_entities_with_generated_PKs(int studentCount, int courseCount)
{
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};

var courses = new Course[]
{
new Course{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}
};

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

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

context.SaveChanges();
}

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

public class Course
{
public Guid Id { get; set; }

public string Title { get; set; } = string.Empty;

public int Credits { get; set; }

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

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

public class Student
{
public Guid Id { get; set; }

public string LastName { get; set; } = string.Empty;

public string FirstMidName { get; set; } = string.Empty;

public DateTime EnrollmentDate { get; set; }

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

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

public enum Grade
{
A, B, C, D, F
}

public class Enrollment
{
public Guid Id { get; set; }

public Guid CourseId { get; set; }

public Guid StudentId { get; set; }

public Grade? Grade { get; set; }

public virtual Course Course { get; set; } = new();

public virtual Student Student { get; set; } = new();

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

private class UniversityContext : DbContext
{
public UniversityContext(DbContextOptions options)
: base(options)
{
}

public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>(builder =>
{
builder.ToTable("Courses");

builder.HasKey(x => x.Id);

builder.Property(x => x.Id)
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEWSEQUENTIALID()");

builder.Property(x => x.Title)
.IsRequired()
.HasMaxLength(50);

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

modelBuilder.Entity<Student>(builder =>
{
builder.ToTable("Students");

builder.HasKey(x => x.Id);

builder.Property(x => x.Id)
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEWSEQUENTIALID()");

builder.Property(x => x.LastName)
.IsRequired()
.HasMaxLength(50);

builder.Property(x => x.FirstMidName)
.IsRequired()
.HasMaxLength(50);

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

modelBuilder.Entity<Enrollment>(builder =>
{
builder.ToTable("Enrollments");

builder.HasKey(x => x.Id);

builder.Property(x => x.Id)
.ValueGeneratedOnAdd()
.HasDefaultValueSql("NEWSEQUENTIALID()");

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

builder.HasOne(t => t.Course)
.WithMany(t => t.Enrollments)
.HasPrincipalKey(d => d.Id)
.HasForeignKey(d => d.CourseId)
.OnDelete(DeleteBehavior.Cascade);

builder.HasOne(t => t.Student)
.WithMany(t => t.Enrollments)
.HasPrincipalKey(d => d.Id)
.HasForeignKey(d => d.StudentId)
.OnDelete(DeleteBehavior.Cascade);
});
}
}

private class EntityA
{
public int Id { get; set; }
Expand Down

0 comments on commit f22054d

Please sign in to comment.