【问题标题】:Access Entity Framework ViewModel properties in View using Lambda Expressions使用 Lambda 表达式在视图中访问实体框架 ViewModel 属性
【发布时间】:2017-07-12 20:48:04
【问题描述】:

我对这篇 Rachel Appel blog 帖子很感兴趣,该帖子有一个引用 ViewModel 的 View,并且在 View 中可以使用 Lambda 表达式访问 ViewModel 的多个实体中的属性:

@Html.EditorFor(model => model.ViewModelEntityName.Property)

我能够访问各个 ViewModel 实体,但不能访问这些实体的属性。这是我的代码:

视图模型

public class PoliciesTrustsViewModel
{
    public ICollection<Insurance> Policies { get; set; } //model in partial class generated by EF database first      
    public ICollection<Companies> Trusts { get; set; } //model in partial class generated by EF database first

    public PoliciesTrustsViewModel(ICollection<Insurance> policies, ICollection<Companies> trusts)
    {
        Policies = policies;

        Trusts = trusts;
    }

控制器

public ActionResult Create()
{
        ICollection<Insurance> policies = db.Insurance.ToList();
        ICollection<Companies> trusts = db.Companies.ToList();

        var myViewModel = new ViewModels.PoliciesTrustsViewModel(policies, trusts);

        return View(myViewModel);
}

查看

我将模型引用设置为 ViewModel:

@model IEnumerable&lt;TrustsInsurance.ViewModels.PoliciesTrustsViewModel&gt;

Lambda 表达式将接受实体名称,但不允许单个实体中的属性。所以

@Html.EditorFor(model =&gt; model.Policies, new { htmlAttributes = new { @class = "form-control" } })

是允许的,但是

@Html.EditorFor(model =&gt; model.Policies.Property, new { htmlAttributes = new { @class = "form-control" } })

产生“不包含定义”错误。我尝试在剃须刀中使用@foreach (var item in Model) 循环以及许多不同的演员表,但没有销售。那么如何使用 lambda 表达式跨多个模型访问属性呢?任何朝着正确方向轻推将不胜感激。

【问题讨论】:

  • 您可能必须@using Your.Property.Types.Namespace 才能使其工作?
  • 要添加到@SimonRowe 的答案,这可能会起作用,但怀疑这是您想要的@Html.EditorFor(model =&gt; model.Policies.First().Property, new { htmlAttributes = new { @class = "form-control" } })

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


【解决方案1】:

我会避免在您的 ViewModel 中嵌入 EF 实体。分:

  • 仅将要呈现的数据放入 ViewModel。
  • 视图应该指向 ViewModel 的属性,这样它更适合渲染和维护。

关系数据很好,但除非您需要构成相关实体的“一切”,否则最好将数据简化为 POCO。传递实体引用通常会导致痛苦。延迟加载 dbContext 范围,或者急切加载“所有内容”以防万一以后可能需要它,在提交时将实体重新关联到 dbContexts.. 比它的价值更混乱。

例如,给定一个视图模型,如果我只关心 FK 和一个漂亮的名称,我想要一个诸如策略和信任(公司)之类的列表,我的视图模型将包含 List&lt;PolicySummary&gt;List&lt;CompanySummary&gt;其中 PolicySummary 是包含 PolicyId 和 DisplayName 的 POCO。 CompanySummary 可能有 CompanyId、CompanyName 和 Address。 (作为格式化的邮寄地址块)这些 POCO 是轻量级的,并且通常可以在一个简单的 .Select() 语句中饱和。在往返过程中,您可以从相关的 dbContext 中检索 ID,以便在您的操作中关联。

【讨论】:

  • 谢谢@StevePy。这很有意义。但是,就我而言,我需要使用 Policies 实体中的所有列,其中有很多列,其中四个来自 Companies。我在 EF 数据库优先应用程序中创建手动 POCO 的知识有限,但乍一看似乎有很多开销。我被我链接到的博客所吸引,因为我认为这可能是从自动生成的实体轻松访问视图中的许多属性的好方法。无论如何,我现在将研究创建 POCO,看看这是否适合我。
  • 再次感谢@StevePy 深思熟虑的回复。轻量级 POCO 绝对是要走的路。代码更易于维护,所有功能逻辑都在控制器中(很好的关注点分离)。对我来说,这是一次关于 MVC 和 EF 的精彩学习之旅,并且很好地提醒了我,依赖 ORM(或与此相关的任何框架)并不能替代应用程序中的良好架构。非常感谢您对更好道路的指导。
【解决方案2】:

我只快速浏览了博客,但最明显的区别是博客中的示例在 ViewModel 中有一个 Customer 实例,但您上面的示例包含两个 ICollection。

因此,Razor 试图寻找的编辑器不是为一个 Policy.Property 而是为它们的整个集合,并且看起来事情失败了。

尝试相同的逻辑,但在 ViewModel 中使用单个 Policy 和 Trust 实例,您应该会得到一个渲染视图。

如果您需要能够编辑集合,则需要进行一些谷歌搜索。您应该在 SO 上找到示例来帮助您。

【讨论】:

  • 谢谢@SimonRowe。在博文中,Rachel Appel 有一个 Customer 实体和一个带有 ViewModel 的 States 字典实体。她的代码允许她通过 @Html.EditorFor(model =&gt; model.Customer.FirstName)@Html.ValidationMessageFor(model =&gt; model.Customer.State) 等语法访问 Customer 和 States 字典的所有属性。我的想法是,我可以将她所做的事情应用于多个完整的实体。我确实尝试编辑 ViewModel 以使用完整实体的单个实例,但我只能访问每个实体而不是其属性(与编辑之前相同)。
  • 如果我们知道您想要达到的目标可能会有所帮助。是的,她的模型有这两项,但对于每个视图模型来说,它们都是单一的,每个视图模型都有一个客户和一个状态。以您的示例为例,有许多政策和许多信任。这对于查看数据来说很好,标准索引视图将向您展示如何为每个字段进行显示,但您建议您希望为集合中每个实体的每个字段都有一个编辑器,而 razor 无法理解如何解释。也许您想要实现的模型可以帮助我们帮助您。
  • 我希望我可以制作一个包含多个实体的 ViewModel。并使用model.entity.property 语法访问关联视图中实体中的属性,因为我需要在创建和编辑视图中混合来自多个实体的多个字段。现在这种语法可能无法使用多个多属性实体,如果不是,我很想听听可接受的选项是什么。在一个完美的世界里,我可能会规范化甚至重新构建数据库,但这不是一个选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
相关资源
最近更新 更多