【问题标题】:can not retrieve data of navigation properties in EF 5, MVC 4无法在 EF 5、MVC 4 中检索导航属性的数据
【发布时间】:2013-05-30 06:01:57
【问题描述】:

我有以下 PersonelInCourse 实体:

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

我这样插入数据没有问题:

...
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();
}
...

我尝试在以下位置检索此信息。但是,这导致了一个异常,我发现所有的导航属性都是空的,所以抛出异常:

@{    
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++;
}

我怎样才能实现我想要的?我的错在哪里?

【问题讨论】:

  • .Load() 添加到您的查询中,以显式加载导航属性。
  • 模型在顶部定义的位置,如@model namespance.Models.Navigation
  • 我已经禁用了延迟加载,我也在其他地方使用过这种方法,在那里我没有问题。
  • 代码优先吗?可以添加映射定义吗?

标签: asp.net-mvc entity-framework asp.net-mvc-4 navigation-properties


【解决方案1】:

您应该添加Include() 以显式加载导航属性。

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

这将在一个查询中加载PersonnelInCourses和他们的Personnel

如果您需要加载更多属性,只需链接更多 .Include("") 子句。

【讨论】:

  • 好的。我还需要人员中另一个导航器的信息(如您所见)。我也需要包括那个 navpr 吗?如果有,怎么做?
  • 只需在同一个查询中添加另一个.Include("...")
  • 我觉得你应该在.Where之前写.Include
  • 您是否尝试过我之前的建议,即在查询末尾添加.Load()?它应该显式加载所有导航属性。
【解决方案2】:

尝试保持PtDbContext 处于活动状态,直到您完成处理来自它的数据并明确测试导航属性:

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

【讨论】:

  • DbContext 还活着。实际上,此表是报表的预览。人员不能为空!因为相关的外键不为空。我必须找到一种方法来检索这些导航属性
【解决方案3】:

找到了! (基于@Liel 的cmets):

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

亲爱的 Liel,您必须在 .Where() 之前添加 .Include() ...非常感谢您的提示。

【讨论】:

  • 这解决了我离开隐身模式登录和投票的大问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 2020-05-30
相关资源
最近更新 更多