Strange.
Passing the PK values in the CTor of the EnrollmentEntity, makes the framework attempt to fetch the entity. So please set the PK values outside the CTor.
Also please populate the enrollments collection outside of the transaction block (before starting the transaction).
So your code should look like:
public static bool EnrollStudentsIntoClass(List<int> studentsToAdd, int classId, List<int> semesterIds, out string error)
{
// First delete all students in selected class and semesters
// Then add the new students. Do all in one transaction
// Go through each semester and student to create their enrollment record
EnrollmentCollection enrollments = new EnrollmentCollection();
foreach (int semesterId in semesterIds)
{
foreach (int studentId in studentsToAdd)
{
//EnrollStudentIntoClass(studentId, classId, semesterId);
var enrollment = new EnrollmentEntity();
enrollment.ClassId = classId;
enrollment.SemesterId = semesterId;
enrollment.StudentId= studentId;
enrollments.Add(enrollment));
}
}
Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "UpdateEnrollment");
error = string.Empty;
try
{
// Delete all students in selected class and semester using the transaction
DeleteAllStudentsInClass(classId, semesterIds, trans, out error);
// Enroll new students into selected class for selected semesters
trans.Add(enrollments);
enrollments.SaveMulti();
trans.Commit();
return true;
}
catch (Exception e)
{
error = e.Message;
trans.Rollback();
return false;
}
}