Question

I have the following PersonelInCourse entity:

public partial class PersonnelInCourse
{
    public int ID { get; set; }
    public string PersonnelID { get; set; }
    public string CourseID { get; set; }
    public int HoursInCourse { get; set; }
    public byte IsApproved { get; set; }
    public byte IsPassed { get; set; }
    public Nullable<int> RewardDetailID { get; set; }
    public string RejectReason { get; set; }
    public string FailReason { get; set; }

    public virtual Course Course { get; set; }
    public virtual RewardDetail RewardDetail { get; set; }
    public virtual Personnel Personnel { get; set; }
}

I insert data like this and it has no problem:

...
PersonnelInCourse p = new PersonnelInCourse();
p.CourseID = id;
p.PersonnelID = User.Identity.Name;
p.HoursInCourse = 0;
p.IsApproved = 0;
p.IsPassed = 0;            
db.PersonnelInCourses.Add(p);
try
{
    db.SaveChanges();
}
...

I try to retrieve this info somewhere like the following. However, this causes an exception and I found out that all of navigation properties are null, so the exception throws:

@{    
var psic = new Models.PtDbContext().PersonnelInCourses.Where(p => p.CourseID == Model.ID);
var c = new Models.PtDbContext().Courses.Find(Model.ID);
int i = 1;
} // these all are ok.
...

@foreach (var p in psic)
{
    <tr style="border-bottom: 1px dotted black;">
        <td>@i.ToString()</td>
        <td>@string.Concat(p.Personnel.FirstName, " ", p.Personnel.LastName)</td> 
    //the exception throws from here, because the navigation property Personnel is null, and all other navPrs also are null.
        <td>@p.Personnel.Post.PostName</td>
        <td>@p.PersonnelID</td>
    </tr>

    i++;
}

How can I achieve what I want? Where is my mistake?

Was it helpful?

Solution 3

Found it! (based on comments of @Liel):

var psic = new jqPersonnelTraining.Models.PtDbContext().PersonnelInCourses
    .Include("Personnel").Include("Personnel.Post").Where(p => p.CourseID == Model.ID);

dear Liel, you must add .Include() before .Where() ... Thanks a lot for your tips.

OTHER TIPS

You should add Include() for explicit loading of navigation properties.

var psic = new Models.PtDbContext().PersonnelInCourses..Include("Personnel").Where(p => p.CourseID == Model.ID);

This will load PersonnelInCoursesand their Personnel in one query.

In case you need to load some more properties, simply chain more .Include("") clauses.

Try keeping PtDbContext alive until you have finished processing data from it and explicitly test for the navigation property:

@using (var context = new Models.PtDbContext()){    
    var psic = context.PersonnelInCourses.Where(p => p.CourseID == Model.ID);
    var c = context.Courses.Find(Model.ID);
    int i = 1;
<table>
    @foreach (var p in psic)
    {
    <tr style="border-bottom: 1px dotted black;">
        <td>@i.ToString()</td>
        @if (p.Personnel == null)
        {
        <td><b>not found</b></td> 
        <td><b>not found</b></td>
        }
        else
        {
        <td>@string.Concat(p.Personnel.FirstName, " ", p.Personnel.LastName)</td> 
        <td>@p.Personnel.Post.PostName</td>
        }
        <td>@p.PersonnelID</td>
    </tr>
</table>
        @i++;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top