C# 当我使用投影创建展平视图模型时,我丢失了元数据

C# 当我使用投影创建展平视图模型时,我丢失了元数据,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,许多教程都说,当我必须从controller传递数据以查看时,最好的方法是创建一个更平坦的viewMoldel。 此解决方案还解决了其他问题(如急切加载问题)。 我担心的是,当我创建一个展平视图模型时,我会丢失通过注释存储在实体中的所有信息 假设我有一个由 class product{ [DisplayName("Name")] public String Name{get;set;} [DisplayName("Image")] public String Image{g

许多教程都说,当我必须从controller传递数据以查看时,最好的方法是创建一个更平坦的viewMoldel。 此解决方案还解决了其他问题(如急切加载问题)。 我担心的是,当我创建一个展平视图模型时,我会丢失通过注释存储在实体中的所有信息

假设我有一个由

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;}

}
要渲染显示产品信息的网格,许多教程说,最好的方法是提供如下展平视图模型:

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

我担心的是我需要在viewModel中重新编写所有DisplayName注释。

您的视图模型就是您的数据消耗用例。如果需要元数据,则视图模型需要展开或以其他方式支持它。您可能需要动态添加它?或者,如果这太繁重,那么您需要在编译时对其进行编码

编辑

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


您要做的是将真相的来源放入一个程序集中,然后使用T4转换文件在另一个程序集中使用反射从该程序集中创建其他表示

视图模型是您的数据消耗用例。如果需要元数据,则视图模型需要展开或以其他方式支持它。您可能需要动态添加它?或者,如果这太繁重,那么您需要在编译时对其进行编码

编辑

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


您要做的是将真相的来源放入一个程序集中,然后使用T4转换文件在另一个程序集中使用反射从该程序集中创建其他表示

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

详情如下:

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();
            }
        }
} 

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

详情如下:

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();
            }
        }
} 

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

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

方法是实现一个定制的AssociatedMetadataProvider。这并不像您想象的那么多,您可以实现一个,从xml文件、数据库、约定甚至好友类型生成元数据,就像当前的一样

对于当前的实现,您需要做的唯一不同的事情是允许好友类型包含其应用的模型上不存在的字段/属性,因为这是当前唯一阻止您创建好友类型的事情,您可以将其应用于您的特定模型的所有视图/编辑器模型

这需要一些工作,取决于它能为您节省多少时间,但不要忘记大部分MVC源代码都是可用的,您不需要做太多更改


Martin

实现方法是实现一个定制的关联元数据提供程序。这并不像您想象的那么多,您可以实现一个,从xml文件、数据库、约定甚至好友类型生成元数据,就像当前的一样

对于当前的实现,您需要做的唯一不同的事情是允许好友类型包含其应用的模型上不存在的字段/属性,因为这是当前唯一阻止您创建好友类型的事情,您可以将其应用于您的特定模型的所有视图/编辑器模型

这需要一些工作,取决于它能为您节省多少时间,但不要忘记大部分MVC源代码都是可用的,您不需要做太多更改


Martin

我的首要任务是采用更智能的方式编写更少的代码,并尽可能将事情集中在一个地方。例如,如果明天我更改给定产品属性的dispalyname,我希望此更改在我的所有站点中进行,我不想记住我使用此属性的所有位置,浪费时间查找和替换它。我的首要任务是以更智能的方式编写更少的代码,并尽可能将内容集中在一个地方。例如,如果tomonrow我更改了给定产品属性的dispalyname,我希望此更改发生在我的所有站点中,我不想记住我使用此属性的所有位置并浪费时间查找和替换它。我使用UiGridComponent从注释中检索元数据(如HtmlHelper.LabelFor(..)。因此,ProductName属性没有DisplayName属性。UiGridComponent不知道ProductDisplayName。我使用UiGridComponent从注释中检索元数据(如HtmlHelper.LabelFor(…)。因此,ProductName属性没有DisplayName属性。UiGridComponent不知道ProductDisplayName。我的结论是没有简单的解决方案来解决我的问题。我的结论是没有简单的解决方案来解决我的问题。