Usando System.ComponentModel.DataAnnotations com o Entity Framework 4.0

Estou trabalhando com o MVC3 e usando Entity Framework 4.0 Entities como meu modelo. Até agora, tudo funciona muito bem ao usá-lo como um modelo (todas as operações brutas / geração de páginas funcionam prontamente). Eu estou querendo saber, porém, como você obtém os mesmos labels robustos e informações de validação de quando você gera um modelo manualmente?

Aqui está um exemplo do que quero dizer. Esta é uma class gerada pelo projeto MVC3 de amostra:

public class LogOnModel { [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } 

Com o exemplo acima, você pode especificar o que é renderizado em um label para o campo (Exibição) e o tipo de campo a ser usado (Senha). No entanto, quando tento usar a estrutura de entidade e pressioná-la para a visualização abaixo, vejo que as etiquetas geradas automaticamente são apenas nomes de campo, e não qualquer coisa que eu queira que o usuário veja / precise ler:

 @using (Html.BeginForm()) { @Html.ValidationSummary(true) 
Person
@Html.LabelFor(model => model.FirstName)
@Html.EditorFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName)
@Html.LabelFor(model => model.MiddleName)
@Html.EditorFor(model => model.MiddleName) @Html.ValidationMessageFor(model => model.MiddleName)
@Html.LabelFor(model => model.LastName)
@Html.EditorFor(model => model.LastName) @Html.ValidationMessageFor(model => model.LastName)
@Html.LabelFor(model => model.Birthdate)
@Html.EditorFor(model => model.Birthdate) @Html.ValidationMessageFor(model => model.Birthdate)

}

insira a descrição da imagem aqui

Minha pergunta é: Como adiciono essas decorações extras às entidades que são geradas usando o EF4? Existe algo além de System.ComponentModel.DataAnnotations que eu deveria estar usando? Eu sei que as entidades são regeneradas e provavelmente não é uma boa idéia adicionar isso diretamente ao código das entidades, mas, por algum motivo, não consigo pensar em uma abordagem melhor do que inserir manualmente o texto da etiqueta na visualização (não é razoável tem que fazer isso, isso é MVC!). Eu quero mantê-lo de modo que o aplicativo seja dynamic o suficiente para poder ter as informações de exibição corretas para o meu modelo e manter uma abordagem de MVC. Como eu faço isso?

Eu não fiz isso para a ASP.NET MVC (apenas para o Silverlight), mas acredito que os mesmos princípios se aplicariam. Você pode criar uma “class de amigo de metadados” como abaixo, porque os tipos gerados pelo EF devem ser parciais, portanto, você pode adicionar um pouco mais a eles (como o MetadataTypeAttribute) e criar essa class de irmãos que contém os metadados.

É meio feio, mas deve funcionar. É algo como isto (assumindo que a entidade EF é chamada de “Person”):

 [MetadataType(typeof(PersonMetadata))] public partial class Person { // Note this class has nothing in it. It's just here to add the class-level attribute. } public class PersonMetadata { // Name the field the same as EF named the property - "FirstName" for example. // Also, the type needs to match. Basically just redeclare it. // Note that this is a field. I think it can be a property too, but fields definitely should work. [Required] [Display(Name = "First Name")] public string FirstName; } 

O mesmo que acima, mas com todos os detalhes, e funciona

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

E aqui está o código

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace Validate.Models { [MetadataType(typeof(PersonMetadata))] public partial class Person { // Note this class has nothing in it. It's just here to add the class-level attribute. } public class PersonMetadata { // Name the field the same as EF named the property - "FirstName" for example. // Also, the type needs to match. Basically just redeclare it. // Note that this is a field. I think it can be a property too, but fields definitely should work. [Required] [Display(Name = "Enter Your Name")] public string FirstName; } } 

Como a resposta de Austin Lamb , em vez disso, aninhando a class MetaData na class de entidade, reduzindo assim o número de classs em sua lista pública de namespaces e eliminando a necessidade de ter um nome exclusivo para cada class de metadados.

 using System.ComponentModel.DataAnnotations; namespace Validate.Models { [MetadataType(typeof(MetaData))] public partial class Person { public class MetaData { [Required] [Display(Name = "Enter Your Name")] public string FirstName; //... } } }