【问题标题】:Entity IEnumerable only getting base class - not derived classes实体 IEnumerable 仅获取基类 - 不是派生类
【发布时间】:2016-02-18 18:22:07
【问题描述】:

我创建了一个名为Customer 的基类,其中包含两个派生类PrivateCustomer 和BusinessCustomer。 这是我的实体模型:

在我看来,我需要显示一个所有客户的列表。但我也想表明他们是企业客户还是私人客户,并获得一些具体信息,例如私人客户。

我的视图需要模型@model IEnumerable<CarDealerMVC.Models.Customer>,它通过return View(db.CustomerSet.ToList());从控制器获取模型

但是,该列表不包含派生对象 - 仅包含基础 (Customer)。因此,虽然我可以使用@if (item is Models.PrivateCustomer) 检查它是企业客户还是私人客户,但我无法打印PrivateCustomer 特定属性,例如心肺复苏术

我该怎么做?

【问题讨论】:

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


    【解决方案1】:

    这可以使用DisplayFor 模板来实现,为每个不同的具体元素类型声明@Model 类型。

    以Shared/DisplayTemplates/PrivateCustomer.cshtml为例:

    @Model PrivateCustomer
    @Model.Id
    @Model.Name
    @Model.Phone
    @Model.Cpr
    @Model.Genger
    

    还有Shared/DisplayTemplates/BusinessCustomer.cshtml:

    以Shared/DisplayTemplates/BusinessCustomer.cshtml为例:

    @Model BusinessCustomer
    @Model.Id
    @Model.Name
    @Model.VatNumber
    @Model.Fax
    

    然后在您的视图中,您需要按如下方式循环集合,使用反射在运行时定位模板:

    @foreach(var item in Model)
    {
        @Html.DisplayFor(x => item, item.GetType().Name)
    }
    

    这种方式抽象出特定的具体实例,但不幸的是意味着重复您的公共基础属性,即Id、Name 等。

    【讨论】:

    • 好主意,但这意味着您无法控制显示哪些属性(因此它将包括 FK ID 字段等),以及它们的顺序显示。除非您使用自定义属性等来装饰模型属性。
    • @GaryMcGill 您可以完全控制显示哪些属性。这使用类的属性名称的反射来查找手动创建的 DisplayFor 模板。属性顺序由您决定,不会呈现 FK。
    • 这是一个好方法。但我会更进一步。我将为这些类型中的每一种创建视图模型。这可以消除@GaryMcGill 对拥有不需要的属性等的担忧,并且您还可以添加属性。另一个最大的优势是您甚至可以组合字段并将它们作为单个属性公开以查看。例如:地址
    • @KosalaW 这不会有不需要的属性,它使用反射来手动渲染您自己创建的编辑器模板。您也可以使用 ViewModels,因为无论如何这是一种很好的做法,但使用相同的方法。
    • @hutchonoid:是的。我知道。这取决于您的编辑器模板。但是,这些模板有时不是由您最有经验的开发人员设计的。我们真的不想向他们公开敏感字段。我们要不要? :)
    【解决方案2】:

    通过转换为适当的类型。

    例如:

    @foreach (var customer in Model)
    {
        var businessCustomer = customer as Models.BusinessCustomer;
        if (businessCustomer != null)
        {
            @businessCustomer.VatNumber
        }
    
        var privateCustomer = customer as Models.PrivateCustomer;
        if (privateCustomer != null)
        {
            @privateCustomer.Cpr
        }
    }
    

    【讨论】:

    • @Henk 如果不在视图中,您要将什么模型类型(以及具有哪些属性)发送到视图?不过,我更喜欢 Hutch 的方法。
    猜你喜欢
    • 2013-10-15
    • 2023-03-19
    • 2016-02-23
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    相关资源
    最近更新 更多