Asp.net mvc MVC视图中的动态类与模型类相似但不相同

Asp.net mvc MVC视图中的动态类与模型类相似但不相同,asp.net-mvc,dynamic,Asp.net Mvc,Dynamic,假设我们有一个ASP.NET MVC视图,如下所示: <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %> <%: Html.EditorFor(model => model.ServiceDate) %> <%: Html.ValidationMessageFor(model => model.ServiceDate, "*")%>

假设我们有一个ASP.NET MVC视图,如下所示:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<%: Html.EditorFor(model => model.ServiceDate) %>
<%: Html.ValidationMessageFor(model => model.ServiceDate, "*")%>

型号.服务日期)%>
model.ServiceDate,“*”>
我们有相似但不完全相同的模型类,例如
Invoice
Quote
,它们都包含
ServiceDate
属性。这两个类不是从同一个基类继承的,实际上它们当前没有基类

  • 当这两个基类由EF生成时,如何让它们从同一基类继承?如果我能够做到这一点,我可以替换
    动态
    ,并将基类指定为视图的强类型

  • 我的印象是,
    dynamic
    就是为这种情况而构建的。但显然它不起作用,因为从LINQ到EF显然有一个例外:

    CS1963:表达式树不能包含动态操作


  • 尽管VS 2010编辑器中确实指出表达式将在运行时解析,但事实并非如此,而是错误地失败了。

    您似乎试图在视图中使用EF生成的类。我建议你不要这样做。这就是ViewModels应该做的。不要害怕为每个视图创建视图模型(即使必须重复某些属性),并避免传递模型。同时,拥有强类型的视图就像拥有弱类型的视图一样。再一次:避免它们:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeAdaptedViewModel>" %>
    <%: Html.EditorFor(model => model.ServiceDate) %>
    <%: Html.ValidationMessageFor(model => model.ServiceDate, "*")%>
    
    
    型号.服务日期)%>
    model.ServiceDate,“*”>
    
    首先,您使用的是哪个EF版本? 我想你用的是EFv1,对吧?您可以向来自EF的模型添加继承。它们都被框架定义为parcial类。这意味着您可以创建另一个具有从基类继承的相同名称(也是parcial)的类

    顺便说一下,我建议您在这种情况下使用ViewModels。避免仅仅为了重用某些属性而使用继承,应使用继承向类中添加多态行为。

    1)实体框架生成的类使用
    partial
    关键字。这意味着您可以轻松地扩展它们,而不必担心代码生成会抹去您的更改

    假设EF生成:
    public分部类Customer

    您可以定义另一个名为Customer_Partial.cs的.cs文件(只是我的个人命名偏好),然后执行以下操作:

     public partial class Customer : IMySharedInterface
     {  
     }
    
    然后,您的查看页面使用:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IMySharedInterface>" %>
    
    
    
    然后以强类型方式访问模型属性


    2) 我认为这是因为你把一个IQueryable传递到你的视图中。不过我不确定。有了上述解决方案,您就不必担心了。

    我已经一遍又一遍地讨论了这个问题,在某些情况下,我会创建自定义模型类。但在这种情况下,没有必要这样做,一切都很好,我很好地使用分部类来扩展那些EF类或添加验证注释,所以总的来说它工作得很好,维护起来很简单,我不会更改它。我知道它带来的影响和最佳实践,必须遵循(但不是盲目的)。@mare,总是需要使用视图模型,相信我,这将使您的生活更加轻松。投票被否决,因为使用分部类扩展不允许更改C#中的基类-分部声明不能指定不同的基类。我将EFv4与.NET4和ASP.NETMVC2.True一起使用。但您可以使用ServiceDate属性创建接口,并在部分声明中实现该接口。这样,可以将接口指定为视图的强类型。对吗?还是我又错了?我现在不支持VS。@mare,当然,除了代码示例、接口而不是基类之外,我重复了它,试图回答#2,并且没有因为在视图中使用EF类而责骂你。。)向上投票,但接受Guilherme的回答,因为他需要分数;)@我很高兴我付出了额外的努力来改进他的答案。