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

かみそりの cshtml ページ (自動 CRUD で定義されたインデックス ページ) があり、部門から始めて、関連する CareerFields を読み込むことができます。ただし、クラスターをロードしようとすると、エラー メッセージが表示されます。

「/」アプリケーションでサーバー エラーが発生しました。値を null にすることはできません。パラメーター名: source 説明: 現在の Web 要求の実行中に未処理の例外が発生しました。エラーの詳細とコード内のどこでエラーが発生したかについては、スタック トレースを確認してください。

例外の詳細: System.ArgumentNullException: 値を null にすることはできません。パラメータ名: ソース

これがコントローラーからの私のインデックスメソッドです(コメントアウトされた行は私が試したものでもあることに注意してください)

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

これが問題だとは言いませんが、値が null でないことを確認しましたか? ラインで

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

viewModel.CareerFieldsnullである可能性はありますか?

いくつかの補足事項として:

  • nullables がある場合の null チェックでは、HasValue メソッドを使用することをお勧めします。

    if (divisionID.HasValue)
    {
        ...
    }
    
  • の使用はSingle()少し気まぐれである可能性があり、要素が存在しない場合、または複数存在する場合は例外をスローする可能性があります。First()複数を処理するために使用できます (ただし、一致するものがない場合はスローされます)。SingleOrDefault()ゼロまたは 1 つの結果FirstOrDefault()を処理し、ほとんどのことを処理します。

  • ラムダを単一の例に入れることで式を保存できます

    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がnullであるという事実は、特定の部門に関連するCareerFieldsがないことを意味するため、コードに独自の問題を課します. これは、Single() 呼び出しがヒットするとThe source contains no elements、CareerFields に空のハッシュセットが含まれるため、例外がスローされることを意味します。これは、SingleOrDefault() を変更することで修正できます。

于 2012-07-28T00:07:56.080 に答える