【问题标题】:Getting related data from viewmodel?从视图模型中获取相关数据?
【发布时间】:2017-01-10 04:38:34
【问题描述】:

我在使用 Entity Framework 获取某些相关数据的值时遇到问题。基本前提是“物业”属于单个“社区”,“社区”属于单个“区域”

我的房产有以下型号:

public class Property
{
    public int ID { get; set; }

    public string Name { get; set; }

    public int CommunityID { get; set; }

    public int PropertyTypeID { get; set; }

    public virtual Community Community { get; set; }

}

对于我的社区模型..

public class Community
{
    public int ID { get; set; }

    public string Name { get; set; }

    public Region Region { get; set; }

    public virtual ICollection<Property> Properties { get; set; }
}

对于我所在的地区...

public class Region
{
    public int ID { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Community> Communities { get; set; }
}

我已将所有这些放在一个视图模型中...

public class PropertyDetailViewModel
{
    public string Name { get; set; }

    public virtual Community Community { get; set; }

    public virtual Region Region { get; set; }
}

但是,当尝试使用以下控制器方法将其推送到视图时会出现问题:

Property property = await db.Property.FindAsync(id);
var viewModel = new PropertyDetailViewModel
{
    Name = property.Name,
    Community = property.Community,
    Region = property.Community.Region
};
return View(viewModel);

在我看来,我正在使用

为区域名称创建一个占位符

@Html.DisplayFor(model => model.Region.Name)

但这显示为空,即使数据库中确实有有效的条目?

【问题讨论】:

  • 在 DB 中有条目是一回事,您是否在视图模型上填充属性?您是否对其进行了调试以查看是否正在设置值?
  • 我一直在阅读的教程似乎使用了虚拟属性。网上快速搜索了一下,调用数据库的时候似乎效率更高,因为它使用了延迟加载。
  • 啊,是的,这是有道理的。让我试一试,我会让你知道我的进展如何。谢谢
  • @Gavin5511 - 在接受急切加载作为最佳选择之前,请确保您了解急切加载的缺点。通过从 Region 导航属性中删除 virtual 关键字,每次在系统中的任何位置加载 Property 实体时,您都将加载整个 Region 对象。假设 Region 是一个小实体,或者总是在加载属性时使用,这可能不是问题。但是想象一下,Region 是一个拥有大量属性和其他相关数据的巨大实体。您可能不想在每次加载 Property 时都加载整个 Region 对象。 YMMV。
  • 谢谢@chambo,我明白了。事实上,我现在已经解决了这个问题,情况恰恰相反。如果您查看我上面的模型,viewmodel 使用的是虚拟属性,但我的数据模型没有。我没有改变两者来使用虚拟,它工作得很好。我不知道为什么这可能会解决它?也许错配会让它感到困惑?

标签: c# asp.net asp.net-mvc entity-framework


【解决方案1】:

您可以使用 include,这样您的区域就不会为空。

Property property = await db.Property.Include(p => p.Community.Region).FirstOrDefaultAsync(p => p.ID == id);

更详细:Include() in LINQ to Entities query

【讨论】:

    【解决方案2】:

    尝试在您的视图模型中展平 Region 对象以仅使用您需要的字段:

    public class PropertyDetailViewModel
    {
        public string Name { get; set; }
    
        public virtual Community Community { get; set; }
    
        public string RegionName { get; set; }
    }
    

    然后更新你的视图模型映射代码:

    Property property = await db.Property.FindAsync(id);
    var viewModel = new PropertyDetailViewModel
    {
        Name = property.Name,
        Community = property.Community,
        RegionName = property.Community.Region.Name
    };
    return View(viewModel);
    

    最后更新您的视图以在视图模型中使用扁平化的 RegionName 属性:

    @Html.DisplayFor(model => model.RegionName)
    

    在查询语句中将其与.Include() 结合使用以提高性能

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      相关资源
      最近更新 更多