实体框架导航属性

时间:2014-02-28 14:33:55

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

我目前正在尝试开发我的第一个.NET MVC应用程序,以便学习主要概念。

在我的应用程序中,我有一个表格,显示动物表中的动物列表。在表格中,我也试图显示动物品种,但是我正在动物表enter image description here

中存储的外键上从品种表中提取品种。

我目前正在尝试使用导航属性来显示品种文本,而不是ID 改变我的动物模型看起来像这样

public partial class Animal
{
    public int AnimalId { get; set; }
    public Nullable<int> UserId { get; set; }
    public string TagNo { get; set; }
    public Nullable<int> Species { get; set; }
    public Nullable<bool> Sex { get; set; }
    public Nullable<int> AnimalBreed { get; set; }
    public Nullable<System.DateTime> DOB { get; set; }
    public Nullable<int> OwnershipStatus { get; set; }
    public Nullable<System.DateTime> DateAdded { get; set; }
    public Nullable<bool> BornOnFarm { get; set; }

    public virtual Breed Breed { get; set; }
}

我的品种模型看起来像

public partial class Breed
{
    public int id { get; set; }
    public Nullable<int> SpeciesID { get; set; }
    public string Breed1 { get; set; }
}

在我看来,我试图从我的动物模型中显示品种字段,如下所示,但品种列只是空的

<td>
  @Html.DisplayFor(modelItem => item.Breed.Breed1)
</td>

最后,这里是我用来将模型发送到视图的代码

List<Animal> Animal1 = (from animals in db.Animals
    where animals.Species == 2 && animals.OwnershipStatus == 1
    && animals.UserId == WebSecurity.CurrentUserId
    select animals).ToList();

return View(Animal1);

2 个答案:

答案 0 :(得分:4)

首先,不要将单个项目复数化。它会在您的代码中造成混淆:

public virtual Breed Breed { get; set; }

-OR -

public virtual ICollection<Breed> Breeds { get; set; }

virtual属性允许延迟加载(首次尝试访问时会发出获取该品种的查询)。您几乎总是希望将virtual包含在属性中,因此如果您实际上并未使用该属性,则Entity Framework不会不必要地发出连接。但是,在这种情况下,您 ,因此您希望通过在查询中加入.Include("Breed")来告诉EF急切加载它。但是,这只是为了优化;这不是你的问题。

你的问题是Razor不知道如何显示Breed。它显然不是普通类型,因为你创建了它。因此,您真正需要的是在Breed上显示您想要的实际属性:

@Html.DisplayFor(m => m.Breed.Breed1)

这是一种替代方法,但它更复杂,并且对于这种情况可能过度杀伤。如果您确实想直接使用Breed,则需要为Breed定义显示模板。您可以通过向名为Views\Shared的{​​{1}}添加新文件夹来实现此目的。在该文件夹中,添加名为DisplayTemplates的视图。此处视图的名称对应于名称,而不是属性名称。在该视图中,您可以执行以下操作:

Breed.cshtml

然后,在您看来,您可以这样做:

@model Namespace.To.Breed
@Html.DisplayFor(m => m.Breed1)

Razor将使用显示模板来呈现适当的内容。就像我说的那样,这样做有点过分,但在更复杂的对象渲染中,它可能会派上用场。

答案 1 :(得分:0)

如果DbContext中未启用延迟加载,则必须明确加载(或使用预先加载)导航属性。

请参阅http://msdn.microsoft.com/en-us/data/jj574232.aspx

你最终会得到类似的东西:

var res = (from animals in db.Animals.Include("Breeds")
                                    where animals.Species == 2 & animals.OwnershipStatus == 1
                                    & animals.UserId == WebSecurity.CurrentUserId
                                    select animals).ToList();