.net mvc 声明一个 属性 来保存通用对象的集合?

.net mvc declare a property to hold a collection of generic objects?

我有一个使用 EF 的 MVC proyect(数据库优先),我已经为一些实体创建了 CRUD。 现在我正在尝试创建一个包含小部件或类似部件的仪表板页面,每个都列出来自不同数据库表的最后 10 个实体(最后创建的 10 个产品,最后 10 个客户等) 要创建小部件,我遵循了本教程 https://www.codeproject.com/Articles/598383/Widgets-in-MVC

所以我有 2 个接口和 2 个实现这些接口的 类:

public interface IWidget
{
    int SortOrder { get; set; }
    string Entity { get; set; }
    string CssClassName { get; set; }
    string HeaderText { get; set; }
    string FooterText { get; set; }
    ISubWidget SubWidget { get; set; }
}

public interface ISubWidget
{
    ICollection<Products> EntitiesList { get; set; }
}


public class Widget : IWidget
{
    public int SortOrder { get; set; }
    public string Entity { get; set; }
    public string HeaderText { get; set; }
    public string FooterText { get; set; }
    public ISubWidget SubWidget { get; set; }
}

public class SubWidget : ISubWidget
{
    public ICollection<Products> EntitiesList { get; set; }
}

然后我有 3 个局部视图:一个用于小部件本身,一个用于子小部件,另一个将充当所有已创建小部件的容器。

@model  Proyect.Comun.Widget.IWidget
<div class="widget">
    <div class="@Model.CssClassName">
        <div class="widgetHeader">
            @Model.HeaderText
        </div>
        <div class="widgetBody">
            @Html.Partial(string.Concat(new[] { "Widget", "/", "_SubWidget" }), @Model.SubWidget)
        </div>
        <div class="widgetFooter">
            @Model.FooterText
        </div>
    </div>
</div>


@model  Proyect.Comun.Widget.ISubWidget
<table>
    @foreach (var item in Model.EntitiesList)
    {
        <tr>
            <td> @Html.DisplayFor(modelItem => item.product_number) </td>
            <td> @Html.DisplayFor(modelItem => item.product_name) </td>
            <td> @Html.DisplayFor(modelItem => item.product_description) </td>
        </tr>
    }
</table>


@model  Fruterias.Comun.Widget.IWidget
@foreach (Proyect.Comun.Widget.IWidget wm in ViewBag.Widgets)
{
    @Html.Partial(string.Concat(new[] { "Widget", "/", "_Widget" }), wm)
}

然后在仪表板控制器中:

public ActionResult Index()
{
    ViewBag.Widgets = GetWidgetData();
    return View();
}


public List<IWidget> GetWidgetData()
{
    var lastWidget = new List<IWidget>{
        new Widget()
        {
            SortOrder = 1,
            CssClassName = "high",
            Entity = "Products",
            HeaderText = "Last Products",
            FooterText = "",
            SubWidget = new SubWidget {
                EntitiesList = db.products.OrderByDescending(p => p.date).Take(10).ToList(),
            }
        },
    };
    return lastWidget;
}

最后在 Dashboard/Index 的视图中:

<p>
    @{
        @Html.Partial("Widget/_WidgetContainer");
    }
</p>

这工作正常并显示了产品实体列表。但现在我想创建与不同实体关联的不同小部件。 当然,问题是 属性 EntitiesList 被声明为 Product 对象的集合,所以我不能用例如 customers 对象填充它。

这里的解决方案是什么?我可以为每种类型的实体创建不同的接口(和 类),但我确信一定有更好的方法...

此外,由于实体模型(产品、客户...)首先由 Entity Framework 数据库生成,我想我无法创建接口并让它们实现该接口(或者我可以吗?) ...(任何时候数据库更改和模型由 EF 重新生成,所有这些都会丢失吗?)

如果您不需要让 EntitiesList 成为特定类型,您可以让 SubWidget 成为通用类型并在实例化时设置其类型。

public class SubWidget<T> : ISubWidget<T> where T : class
{
    public ICollection<T> EntitiesList { get; set; }
}

或者您可以使用动态对象。

public class SubWidget : ISubWidget
{
    public ICollection<dynamic> EntitiesList { get; set; }
}