如果在foreach中出现错误,继续插入

本文关键字:错误 继续 插入 foreach 如果 | 更新日期: 2023-09-27 18:14:15

我有一个嵌套列表,我正在迭代它并将数据插入到我的数据库中,只有当所有子列表项都成功插入到数据库中。

你可以看到我的代码,我使用try catch嵌套迭代,以及外部迭代和整个代码被包装在BeginTransaction.

只要我提供有效的数据,这段代码就可以正常工作。

但是,如果嵌套迭代失败,由于一些验证问题(i.e. SubjectCategoryId not provided ),它在做所有迭代后退出内部foreach,增加外部foreach,尝试执行SaveChanges,但说对象Null引用错误失败。

如果你需要更多的信息,尽管问我。我觉得我遗漏了一些要点,特别是在处理BeginTransaction中的嵌套foreach时。

你看到我的代码结构有什么问题吗?我用EF 5

我代码:

foreach (var student in Student)
{
    using (var transaction = _context.Database.BeginTransaction())
    {
        try
        {
            Student student = new Student
            {
                StudentNo = item.Stu_No,
                Name = item.FullName,
                Description = item.Description,
                Phone = item.ContactNo,
                Address = item.Location
                Status =  item.status
            };
            _context.Student.Add(student);
            _context.SaveChanges(); // Get Object Null reference error for second iteration if child iteration fails. But works fine if no data issue.
             var subjectsInfo = student.Subject_Info.GroupBy(pt => new { pt.Subject_Id, pt.SubjectDesc }).ToList();
             SubjectInfo subInfo = new SubjectInfo();
             SubjectCategory subCat = new SubjectCategory();
             foreach(var subjectInfo in subjectsInfo)
             {
                 try
                 {
                    subInfo.Subject_Id = subjectInfo.Id;
                    subInfo.Description = subjectInfo.Description;
                    subInfo.Id = student.Id;
                    _context.SubjectInfo.Add(subInfo);
                    _context.saveChanges();
                    subCat.SubjectCategoryId = subjectInfo.SubjectCategoryId;
                    subCat.Status = subjectInfo.Status;
                    _context.SubjectCategory.Add(subCat);
                    _context.saveChanges();
                 }
                 Catch(Exception ex)
                 {
                      // catch exception
                 }
             }
        }
        Catch(Exception ex)
        {
        }
    } 
}

My data population:

List<Student> Student= new List<Student>();
Student.Add(new Student
{
    BasicInfo = new BasicInfo
    {
        Stu_No = "1",
        FullName = "Steve Adam",
        ContactNo = "12345",
        Location = "XYZ",
        Status = "Active",
    },
    Subject_Info = new List<Subject_Info>
    {
        new Subject_Info() {
        Subject_Id = "1",
        SubjectDesc = "Math",
        SubjectCategoryId = "",
        Status = active
        },
        new Subject_Info() {
        Subject_Id = "2",
        SubjectDesc = "Physics",
        SubjectCategoryId = "",
        Status = active
        },
    }
});

如果在foreach中出现错误,继续插入

当您创建一个新的学生记录时,您正在覆盖您的循环变量:

foreach (var student in Student)
{
    using (var transaction = _context.Database.BeginTransaction())
    {
        try
        {
            Student student = new Student...

使用不同的变量名

如果你

在你的内部,主题信息,每个循环你需要计算成功的次数:

foreach (var student in Student)
{
    using (var transaction = _context.Database.BeginTransaction())
    {
        try
        {
            Student student = new Student...
            int numSuccesses = 0;
             foreach(var subjectInfo in subjectsInfo)
             {
                 try
                 {
                   ... code omitted for clarity
                   numSuccesses++; // The very last thing you do
                 }     
                 Catch(Exception ex)
                 {
                  // catch exception
                 }
             }
        }
        Catch(Exception ex)
        {
        }
    } 
}

因为只有在至少插入一个主题时才真正想要保存记录,所以如果在subjectsInfo循环之后没有成功,则需要回滚学生记录的插入:

if (numSucesses == 0)
{
    // Roll back the insertion of the student record
}

此外,您应该只捕获那些可以从中恢复的异常并记录错误。拥有一个通用的异常处理程序通常是糟糕设计的标志。