如果在foreach中发生错误,请继续插入

时间:2016-10-22 15:58:15

标签: c# entity-framework

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

您可以看到我使用try catch进行嵌套迭代以及外部迭代的代码,整个代码都包含在BeginTransaction.

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

但是,如果嵌套迭代由于某些验证问题(i.e. SubjectCategoryId not provided )而失败,它会在执行所有迭代后退出内部foreach,增加外部foreach,尝试执行SaveChanges但是失败则说出Object 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)
        {
        }
    } 
}

我的数据人口:

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
        },
    }
});

1 个答案:

答案 0 :(得分:2)

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

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

使用其他变量名称。

如果你

在你的内心,主题信息,foreach循环中,你需要计算成功的数量:

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
}

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

相关问题