修复实验成绩评分方案保存的外键失败
This commit is contained in:
1 parent
0e02d446ba
commit
bcdb00ee2e
2 files changed
+95
-9
No files matched your search
@@ -568,21 +568,39 @@ public sealed class ExperimentGradesController(
|
||||
|
||||
sheet.ContributionWeight = request.ContributionWeight;
|
||||
sheet.PassScore = request.PassScore;
|
||||
db.ExperimentGradeItems.RemoveRange(sheet.Items);
|
||||
var existingItems = sheet.Items.ToList();
|
||||
var existingItemScores = sheet.Records
|
||||
.SelectMany(record => record.ItemScores)
|
||||
.ToList();
|
||||
|
||||
// MySQL must see each replacement item before its score rows. Do not
|
||||
// rely on a single mixed insert/delete batch to infer that order.
|
||||
await using var transaction =
|
||||
await db.Database.BeginTransactionAsync(cancellationToken);
|
||||
db.ExperimentGradeItemScores.RemoveRange(existingItemScores);
|
||||
db.ExperimentGradeItems.RemoveRange(existingItems);
|
||||
foreach (var record in sheet.Records)
|
||||
{
|
||||
record.ItemScores.Clear();
|
||||
record.TotalScore = null;
|
||||
record.IsPassed = null;
|
||||
}
|
||||
sheet.Items = replacementItems;
|
||||
foreach (var record in sheet.Records)
|
||||
foreach (var item in replacementItems)
|
||||
record.ItemScores.Add(new ExperimentGradeItemScore
|
||||
{
|
||||
ExperimentGradeItemId = item.Id
|
||||
});
|
||||
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
foreach (var item in replacementItems)
|
||||
item.ExperimentGradeSheetId = sheet.Id;
|
||||
db.ExperimentGradeItems.AddRange(replacementItems);
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
db.ExperimentGradeItemScores.AddRange(
|
||||
sheet.Records.SelectMany(record => replacementItems.Select(item =>
|
||||
new ExperimentGradeItemScore
|
||||
{
|
||||
ExperimentGradeRecordId = record.Id,
|
||||
ExperimentGradeItemId = item.Id
|
||||
})));
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await transaction.CommitAsync(cancellationToken);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,74 @@ namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class ExperimentGradesControllerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task UpdateSettings_ReplacesItemsAndRecreatesScores()
|
||||
{
|
||||
await using var fixture = await ExperimentGradeFixture.CreateAsync();
|
||||
var project = new ExperimentProject
|
||||
{
|
||||
TeachingTaskId = fixture.Task.Id,
|
||||
Code = "LAB-SETTINGS",
|
||||
Name = "评分方案更新实验",
|
||||
ArrangementMode = ExperimentArrangementMode.Centralized,
|
||||
StartDate = fixture.Term.StartDate,
|
||||
EndDate = fixture.Term.EndDate,
|
||||
Status = ExperimentProjectStatus.Published,
|
||||
PublishedAt = DateTime.UtcNow
|
||||
};
|
||||
fixture.Db.ExperimentProjects.Add(project);
|
||||
await fixture.Db.SaveChangesAsync();
|
||||
|
||||
var administrator = fixture.ExperimentGrades(fixture.AdminScope);
|
||||
await administrator.CreateSheet(
|
||||
new ExperimentGradeSheetRequest(
|
||||
project.Id,
|
||||
1,
|
||||
60,
|
||||
[new ExperimentGradeItemRequest(
|
||||
"旧评分项",
|
||||
ExperimentGradeItemKind.Operation,
|
||||
100)]),
|
||||
CancellationToken.None);
|
||||
var sheetId = await fixture.Db.ExperimentGradeSheets
|
||||
.Select(sheet => sheet.Id)
|
||||
.SingleAsync();
|
||||
fixture.Db.ChangeTracker.Clear();
|
||||
|
||||
Assert.IsType<NoContentResult>(await administrator.UpdateSettings(
|
||||
sheetId,
|
||||
new ExperimentGradeSettingsRequest(
|
||||
1,
|
||||
60,
|
||||
[
|
||||
new ExperimentGradeItemRequest(
|
||||
"操作",
|
||||
ExperimentGradeItemKind.Operation,
|
||||
60),
|
||||
new ExperimentGradeItemRequest(
|
||||
"报告",
|
||||
ExperimentGradeItemKind.Report,
|
||||
40)
|
||||
]),
|
||||
CancellationToken.None));
|
||||
|
||||
fixture.Db.ChangeTracker.Clear();
|
||||
var updatedSheet = await fixture.Db.ExperimentGradeSheets
|
||||
.Include(sheet => sheet.Items)
|
||||
.Include(sheet => sheet.Records)
|
||||
.ThenInclude(record => record.ItemScores)
|
||||
.SingleAsync(sheet => sheet.Id == sheetId);
|
||||
Assert.Equal(["操作", "报告"], updatedSheet.Items
|
||||
.OrderBy(item => item.SortOrder)
|
||||
.Select(item => item.Name));
|
||||
var record = Assert.Single(updatedSheet.Records);
|
||||
Assert.Equal(2, record.ItemScores.Count);
|
||||
Assert.All(record.ItemScores, score => Assert.Null(score.Score));
|
||||
Assert.All(record.ItemScores, score => Assert.Contains(
|
||||
updatedSheet.Items,
|
||||
item => item.Id == score.ExperimentGradeItemId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CollegeAdmin_CanPublishApprovedExperimentGradeSheet()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user