当我使用投影创建一个展平的ViewModel时,我丢失了元数据

时间:2010-11-08 10:21:01

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

许多教程都说当我必须从控制器传递数据时,最好的方法是创建一个flattern viewMoldel。 这个解决方案也解决了其他问题(如急切加载问题)。 我担心的是,当我创建一个flatten viewModel 时,我会丢失通过注释存储在实体中的所有信息

假设我有一个由

组成的模型
class product{
  [DisplayName("Name")] 
  public String Name{get;set;}

  [DisplayName("Image")] 
  public String Image{get;set;}

  [DisplayName("Description")] 
  public String Description{get;set;}

  public String CategoryId{get;set;}
}

class category{
  [DisplayName("Code")] 
  Public String Id{get;set;}

  [DisplayName("Category name")] 
  public String Name{get;set;}

}

要渲染显示产品信息的网格,很多教程都说最好的方法是提供像这样的展平viewModel:

class productGridViewModel{
  Public String ProductName{get;set}
  Public String ProductImage{get;set}
  Public String ProductDescription{get;set}
  Public String CategoryName{get;set}
}

我担心的是我需要再次在viewModel中写入所有DisplayName注释。

4 个答案:

答案 0 :(得分:1)

如果要将模型实体展平为ViewModel,是否应该从模型实体类中删除属性并将其放在ViewModel上?您的模型实体不会用于显示,因此它们不应具有这些属性。

答案 1 :(得分:0)

您的视图模型是您的数据使用用例。如果您需要元数据,则视图模型会变平或以其他方式需要支持它。您可能需要动态添加它吗?或者,如果这太麻烦了,那么你需要在编译时对其进行编码。

编辑。

您可以使用T4转换来确保它保持最新的相关代码。事实上,我们使用它允许用户自定义数据库,从而允许在视图模型中表达自定义。

您所做的是将事实的来源放在一个程序集中,然后使用T4转换文件使用另一个程序集中的反射从此程序集创建其他表示。

答案 2 :(得分:0)

一个简单的解决方案是在viewModel中具有只读属性,该属性读取底层Model对象的元数据。然后,您可以将此元数据与View中的相应控件绑定。

如下:

class productGridViewModel{ 
  Public String ProductName{get;set} 
  Public String ProductImage{get;set} 
  Public String ProductDescription{get;set} 
  Public String CategoryName{get;set} 

public string ProductDisplayName
        {
            get
            {
//Please dont mind this code.. I am sure you can write it in much better way.
                return typeof(Producy).GetProperty("Name").GetCustomAttributes(typeof(DisplayName))[0].ToString();
            }
        }
} 

答案 3 :(得分:0)

实现这一目标的方法是实现自定义的AssociatedMetadataProvider。这并不像你想象的那么多,你可以实现一个从xml文件,数据库,约定甚至伙伴类型生成元数据,就像当前的那样。

您唯一需要对当前实现做出不同的做法是允许好友类型包含它们所适用的模型中不存在的字段/属性,因为这是目前唯一阻止您创建伙伴类型,您可以应用于特定模型的所有视图/编辑器模型。

它有点工作,取决于它会节省多少时间,但不要忘记大多数MVC源代码可用,你不必改变很多

马丁