1

为了简洁起见,我将缩短几节课。下面列出了与此问题相关的相关属性/字段。

public class AcademicYear
{
    [Key]
    public int AcademicYearId { get; set; }
}

public class Division
{
    public Division()
    {
        this.CareerFields = new HashSet<CareerField>();
    }

    [Key]
    public int    DivisionId     { get; set; }

    // Foreign Keys
    public int    AcademicYearId { get; set; }

    // Navigation Properites
    public virtual AcademicYear AcademicYear { get; set; }

    public virtual ICollection<CareerField> CareerFields { get; set; }
}

public class CareerField
{
    public CareerField()
    {
        this.Clusters    = new HashSet<Cluster>();
    }

    [Key]
    public int    CareerFieldId   { get; set; }

    // Foreign Keys
    public int    AcademicYearId  { get; set; }
    public int    DivisionId      { get; set; }


    // Navigation Properties
    public virtual AcademicYear AcademicYear { get; set; }
    public virtual Division     Division     { get; set; }

    public virtual ICollection<Cluster>    Clusters    { get; set; }
}

public class Cluster
{
    public Cluster()
    {
        this.CareerFields = new HashSet<CareerField>();
    }

    [Key]
    public int ClusterId { get; set; }
    {
        // Foreign Keys
        public int    AcademicYearId { get; set; }

        // Navigation Properties
        public virtual AcademicYear AcademicYear { get; set; }

        public virtual ICollection<CareerField> CareerFields { get; set; }
    }
}

public class Pathway
{
    public Pathway()
    {
        this.CareerMajors = new HashSet<CareerMajor>();
    }

    [Key]
    public int    PathwayId      { get; set; }

    // Foreign Keys
    public int    AcademicYearId { get; set; }
    public int    ClusterId      { get; set; }

    // Navigation Properties
    public virtual AcademicYear AcademicYear { get; set; }
    public virtual Cluster      Cluster      { get; set; }

    public virtual ICollection<CareerMajor> CareerMajors { get; set; }
}

public class CareerMajor
{
    public CareerMajor()
    {
        this.Courses        = new HashSet<Course>();
    }

    [Key]
    public int    CareerMajorId     { get; set; }
    public string FirstYearOffered  { get; set; }

    // Foreign Keys
    public int    AcademicYearId    { get; set; }
    public int    PathwayId         { get; set; }

    // Navigation Properties

    [HiddenInput(DisplayValue = false)]
    public virtual AcademicYear      AcademicYear      { get; set; }
    public virtual Pathway           Pathway           { get; set; }

    public virtual ICollection<Course>         Courses        { get; set; }

}

public class Course
{
    public Course()
    {
        this.CareerMajors  = new HashSet<CareerMajor>();
    }

    [Key]
    public int    CourseId       { get; set; }

    // Foreign Keys
    public int    AcademicYearId { get; set; }
    public int?   InstructorId   { get; set; }

    // Navigation Properties
    public virtual ICollection<CareerMajor>  CareerMajors  { get; set; }

    public virtual AcademicYear AcademicYear { get; set; }
}

我还有一个 ViewModel 类来为我的控制器加载所有这些

public class CMSIndex
{
    public IEnumerable<Division> Divisions { get; set; }
    public IEnumerable<CareerField> CareerFields { get; set; }
    public IEnumerable<Cluster> Clusters { get; set; }
    public IEnumerable<Pathway> Pathways { get; set; }
    public IEnumerable<CareerMajor> CareerMajors { get; set; }
    public IEnumerable<Course> Courses { get; set; }
}

我有一个 razor cshtml 页面(自动 CRUD 定义的索引页面),我从 Division 开始,我可以加载相关的 CareerFields。但是,当我尝试加载集群时,我收到错误消息

“/”应用程序中的服务器错误。值不能为空。参数名称:source 描述:在执行当前web请求的过程中发生了一个未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.ArgumentNullException:值不能为空。参数名称:来源

这是来自控制器的索引方法(注意注释掉的行也是我尝试过的)

public ViewResult Index(Int32? divisionID, Int32? careerFieldID, Int32? clusterID, Int32? pathwayID, Int32? careerMajorID, Int32? courseID)
    {
        var viewModel = new CMSIndex();

        viewModel.Divisions = db.Divisions
            .Include(d => d.AcademicYear)
            .Include(d => d.CareerFields)//
            .Include(d => d.CareerFields.Select(cf => cf.Clusters))
            //.Select(c => c.Clusters.Select(cl => cl.Pathways.Select(p => p.CareerMajors.Select(cm => cm.Courses)))))
            .OrderBy(d => d.DivisionName);

        if (divisionID != null)
        {
            ViewBag.DivisionID = divisionID.Value;
            viewModel.CareerFields = viewModel.Divisions.Where(d => d.DivisionId == divisionID.Value).Single().CareerFields;
        }

        if (careerFieldID != null)
        {
            ViewBag.careerFieldID = careerFieldID.Value;
            //viewModel.Clusters = viewModel.CareerFields.Where(cf => cf.CareerFieldId == careerFieldID.Value).Single().Clusters;
            //viewModel.Clusters = viewModel.CareerFields.SelectMany(cf => cf.Clusters);
            viewModel.Clusters = viewModel.CareerFields.Where(cf => cf.CareerFieldId == careerFieldID.Value).Single().Clusters;
        }

        return View(viewModel);
    }

我正在关注有关加载相关数据的 Contoso 教程。我似乎能够加载 1:m 关系,但我不确定如何使用 m:m 执行此操作(例如 CareerFields 和 Clusters)。

而且,我确实有一个初始化程序,它已经加载了要提取的数据,并且我正在传递一个 ID(例如 careerFieldID)。

抛出异常的地方在线:

viewModel.Clusters = viewModel.CareerFields.Where(cf => cf.CareerFieldId == careerFieldID.Value).Single().Clusters;

并且每个评论变体。

任何帮助将不胜感激。

4

1 回答 1

1

并不是说这是问题所在,但是您是否检查过这些值不为空?在行

viewModel.Clusters = viewModel.CareerFields
    .Where(cf => cf.CareerFieldId == careerFieldID.Value).Single().Clusters;

有可能viewModel.CareerFields是空的吗?

作为一些旁注:

  • 当你有空值时,你的空值检查最好使用他们的 HasValue 方法,例如

    if (divisionID.HasValue)
    {
        ...
    }
    
  • 的使用Single()可能有点喜怒无常,如果不存在元素或存在多个元素,可能会引发异常。First()可用于处理多个(但如果不匹配则抛出),SingleOrDefault()将处理零个或一个结果,FirstOrDefault()并将处理大多数事情。

  • 您可以通过将您的 lambda 放在单个中来保存表达式,例如

    viewModel.CareerFields = viewModel.Divisions
        .Single(d => d.DivisionId == divisionID.Value).CareerFields;
    

编辑:我认为您遇到的问题与此答案中的问题相同,您是否可以尝试更改您的类集合,以便在为 null 时在 get 中初始化。例如除法

public class Division
{
    [Key]
    public int    DivisionId     { get; set; }

    // Foreign Keys
    public int    AcademicYearId { get; set; }

    // Navigation Properites
    public virtual AcademicYear AcademicYear { get; set; }

    private ICollection<CareerField> careerFields;
    public virtual ICollection<CareerField> CareerFields { 
        get { return careerFields ?? (careerFields = new HashSet<CareerField>()); }
        set { careerFields = value; } 
    }
}

无论如何,这实际上是我的首选方法,这给您的代码带来了自己的问题,因为 CareerFields 为空的事实意味着对于给定的部门,没有关联的 CareerFields。这意味着当您的 Single() 调用被命中时,它将抛出异常The source contains no elements,因为 CareerFields 将包含一个空的哈希集。这可以通过更改 SingleOrDefault() 来解决。

于 2012-07-28T00:07:56.080 回答