当一个字段可能为空时,使用 foreach 循环填充视图模型?

Populating a View Model with a foreach loop when one field could be null?

我有一些来自旧数据库的旧 tables,我正试图用它来填充视图模型。控制器操作在一个旧的 table 中查找记录,其中电子邮件与当前用户的电子邮件匹配,然后根据从这些匹配项派生的列表填充视图模型。这是我的控制器操作:

public PartialViewResult OldCourses()
    {
        var email = User.Identity.GetEmail();

        var reglist = nb.old_register
            .Where(i => i.email == email).ToList();

        if (reglist != null)
        {
            var viewModel = new OldCourseViewModel();

            foreach (var reg in reglist)
            {
                viewModel.StudentID = reg.studentid;
                viewModel.CourseTitle = nb.old_courses.FirstOrDefault(j => j.courseid == nb.old_Cohorts.FirstOrDefault(h => h.cohortname == reg.cohort).modulename).coursetitle;
                viewModel.Cohort = reg.cohort;
                viewModel.Progpct = nb.student_progress.FirstOrDefault(k => k.studentid == reg.studentid).percentage;
            };


            return PartialView("OldCourses", viewModel);
        }

viewModel.Progpct 到 return 可能为空,因为在 student_progress table 中可能没有条目用于 reglist 中的每条记录。这意味着我得到一个错误,对象引用未设置到对象的实例。

视图模型如下:

public class OldCourseViewModel
{
    public int StudentID { get; set; }
    public string CourseTitle { get; set; }
    public string Cohort { get; set; }
    public decimal? Progpct { get; set; }
    public string icon_class { get; set; }
    public string icon_colour_class { get; set; }
    public string titleabbrev { get; set; }

}

旧table的字段'percentage'如下:

public Nullable<decimal> percentage { get; set; }
旧 table 的

None 具有外键关系,我无法以任何方式更改这些 table 中的任何一个。

我知道 foreach 循环无法处理 null,即使该字段在视图模型中可以为 null。

我的第一个问题是处理这种情况的最佳方法是什么,以便该字段在为 null 时可以 returned null?

我的第二个问题是,如果 reglist 中有多个记录,我如何使 foreach 循环遍历 reglist 中的每个记录并在 View Model 中为每个 reglist 中的记录生成一个新记录?

编辑 - 根据斯蒂芬的建议,我做了以下工作:

var pctcheck = nb.student_progress.FirstOrDefault(k => k.studentid == reg.studentid);

                if (pctcheck != null)
                {
                    viewModel.Progpct = pctcheck.percentage;
                }          

这正确地回答了我的第一个问题。斯蒂芬也在评论中正确回答了我的第二个问题

接受的答案是完成我的第一个问题的最佳方式,而不是我使用的上述答案:

viewModel.Progpct = nb.student_progress.FirstOrDefault(k => k.studentid == reg.studentid)?.percentage;

哪个用了?。运算符执行与 if null 检查相同的工作。

对于第一个问题,即使你修复了它,你也可以在新版本的c#中使用?.运算符

viewModel.Progpct = nb.student_progress.FirstOrDefault(k => k.studentid == reg.studentid)?.percentage;

在旧版本中,您可以使用

viewModel.Progpct = nb.student_progress.Where(k => k.studentid == reg.studentid).Select(m => (decimal?)m.percentage).FirstOrDefault();

对于第二个问题,你可以用类似的东西来简化。

您的模型将是 IEnumerable<OldCourseViewModel>

var email = User.Identity.GetEmail();

var model = nb.old_register.Where(i => i.email == email)
     .Select(reg => new OldCourseViewModel {

           StudentID = reg.studentid,
           CourseTitle = nb.old_courses.FirstOrDefault(j => j.courseid == nb.old_Cohorts.FirstOrDefault(h => h.cohortname == reg.cohort)?.modulename)?.coursetitle;
           Cohort = reg.cohort,
           Progpct = nb.student_progress.FirstOrDefault(k => k.studentid == reg.studentid)?.percentage
       });

return PartialView("OldCourses", model);