问题
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?
回答1:
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 PersonnelInCourses
and their Personnel
in one query.
In case you need to load some more properties, simply chain more .Include("")
clauses.
回答2:
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++;
}
}
回答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.
来源:https://stackoverflow.com/questions/16829007/can-not-retrieve-data-of-navigation-properties-in-ef-5-mvc-4