Agregar anotaciones de datos a una clase generada por el marco de entidad

Tengo la siguiente clase generada por el marco de la entidad:

public partial class ItemRequest { public int RequestId { get; set; } //... 

Me gustaría hacer de esto un campo obligatorio

 [Required] public int RequestId { get;set; } 

Sin embargo, como este código se genera, se borrará. No puedo imaginar una forma de crear una clase parcial porque la propiedad está definida por la clase parcial generada. ¿Cómo puedo definir la restricción de una manera segura?

La clase generada ItemRequest siempre será una clase partial . Esto le permite escribir una segunda clase parcial que está marcada con las anotaciones de datos necesarias. En su caso, la clase parcial ItemRequest se vería así:

 using System.ComponentModel; using System.ComponentModel.DataAnnotations; //make sure the namespace is equal to the other partial class ItemRequest namespace MvcApplication1.Models { [MetadataType(typeof(ItemRequestMetaData))] public partial class ItemRequest { } public class ItemRequestMetaData { [Required] public int RequestId {get;set;} //... } } 

Como MUG4N respondió, puede usar clases parciales, pero en su lugar será mejor usar interfaces . En este caso, tendrá errores de comstackción si el modelo EF no se corresponde con el modelo de validación. Por lo tanto, puede modificar sus modelos de EF sin temor a que las reglas de validación estén desactualizadas.

 using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace YourApplication.Models { public interface IEntityMetadata { [Required] Int32 Id { get; set; } } [MetadataType(typeof(IEntityMetadata))] public partial class Entity : IEntityMetadata { /* Id property has already existed in the mapped class */ } } 

PD: si utiliza un tipo de proyecto que difiere de ASP.NET MVC (cuando realiza la validación manual de datos), no olvide registrar sus validadores

 /* Global.asax or similar */ TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity)); 

Encontré una solución como la respuesta de MUG4N , pero anidando la clase MetaData dentro de la clase de entidad, reduciendo así el número de clases en su lista de espacio de nombres público y eliminando la necesidad de tener un nombre único para cada clase de metadatos.

 using System.ComponentModel.DataAnnotations; namespace MvcApplication1.Models { [MetadataType(typeof(MetaData))] public partial class ItemRequest { public class MetaData { [Required] public int RequestId; //... } } } 

Esta es una especie de extensión a la respuesta @dimonser si regeneras tu modelo db tendrás que volver a agregar manualmente las interfaces en esas clases.

Si tienes estómago para eso, también puedes modificar tus plantillas .tt :

Aquí hay un ejemplo de interfaces de autogeneración en algunas clases, este es un fragmento de .tt simplemente reemplaza el método EntityClassOpening en el tuyo con el siguiente (y obviamente var stringsToMatch con tus nombres de entidades e interfaces).

 public string EntityClassOpening(EntityType entity) { var stringsToMatch = new Dictionary { { "Answer", "IJourneyAnswer" }, { "Fee", "ILegalFee" } }; return string.Format( CultureInfo.InvariantCulture, "{0} {1}partial class {2}{3}{4}", Accessibility.ForType(entity), _code.SpaceAfter(_code.AbstractOption(entity)), _code.Escape(entity), _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)), stringsToMatch.Any(o => _code.Escape(entity).Contains(o.Key)) ? " : " + stringsToMatch.Single(o => _code.Escape(entity).Contains(o.Key)).Value : string.Empty); } 

Ninguna persona normal debería hacer esto para sí misma, se ha demostrado en la Biblia que uno va al Infierno por esto.

No estoy seguro de cómo hacer lo que está pidiendo, pero hay una forma de evitarlo. La validación dinámica de datos sobrescribiendo los GetValidators de su DataAnnotationsModelValidatorProvider personalizado. En él puede leer las reglas para validar cada campo (de una base de datos, archivo de configuración, etc.) y agregar validadores según sea necesario. Tiene los valores agregados de que su validación ya no está estrechamente vinculada al modelo y puede modificarse sin necesidad de reiniciar el sitio. Por supuesto, podría ser excesivo para su caso, ¡pero fue ideal para el nuestro!

Modifique la plantilla T4 agregando anotaciones requeridas, este archivo generalmente se llama MODELNAME.tt

encuentre dónde está la T4 creando la clase y los métodos para saber dónde colocarlos.

  < #=codeStringGenerator.IgnoreJson(navigationProperty)#> //create this method in file public string IgnoreJson(NavigationProperty navigationProperty){ string result = navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? "" : @"[JsonIgnore] [IgnoreDataMember]"; return result; } 

También necesitarás agregar los espacios de nombres;

 < #=codeStringGenerator.UsingDirectives(inHeader: false)#> using System.ComponentModel.DataAnnotations; using Newtonsoft.Json; using System.Runtime.Serialization; 

Reconstruya sus clases guardando su modelo, todos sus métodos deben ser anotados.