2009-06-26 15 views

Respuesta

35

Puede hacer esto especificando un tipo de metadato que refleje las propiedades y se use simplemente para la atribución.

[MetadataType(typeof(Dinner_Validation))] 
public partial class Dinner 
{} 

public class Dinner_Validation 
{ 
    [Required] 
    public string Title { get; set; } 
} 

Steve Smith blogs sobre él here.

Desafortunadamente, el enfoque anterior es frágil para la refactorización. Otra opción es usar las nuevas entidades POCO. Estos evitan la generación de código en tiempo de compilación por lo que yo sé. No los he usado todavía así que no puedo comentar sobre ningún inconveniente o desventaja.

+0

Me acababa de enamorar de EF cuando de repente me di cuenta de que los atributos en mis entidades serían prácticamente inexistentes debido a la forma en que se manejan. Grrrr. – Chev

+4

Al reflejar, 'assembly.GetType (typeof (Dinner) .ToString(). GetProperties()', 'property.Attributes' es nulo y' property.GetCustomAttributes (typeof (RequiredAttribute)) 'devuelve una matriz de longitud cero - should uno refleja Dinner_Validation o es algo diferente? – lukiffer

0

No creo que puedas. El generador declara todas las clases como parciales, lo que le permite extenderlo, pero no le permitirá marcar propiedades con atributos personalizados, ya que simplemente generará sobre ellos. Lo único que puedes hacer es escribir tus propias entidades.

+0

Esto puede haber sido el caso, pero hay un par de opciones hoy en día. Ver mi respuesta para obtener información. –

8

Puede crear la interfaz y declarar el atributo en la interfaz.

partial class Person : IPerson {} 

public interface IPerson 
{ 
    [Required] 
    string Name { get; set; } 
} 
+2

Como nota al margen para futuros lectores, esto * no * funciona con la validación de asp.net-mvc. –

11

Puede añadir esto a archivo EDMX, con el diseñador también:

<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" > 
      <Documentation> 
       <Summary>[MyCustomAttribute]</Summary> 
      </Documentation> 
</Property> 

y reemplazar T4:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Con:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
    #> 
    <#=edmProperty.Documentation.Summary#> 
<#+ 
    } 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 
+0

Buena solución ... – Omtara

+0

HI, ¿cómo cambio esa plantilla T4? creó un archivo Model1.tt y que es todo negro en texto y parece ser otra sintaxis. – pungggi

2

puede agregar a este al archivo EDMX, con Designer también:

<Property Name="Nome" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" > 
      <Documentation> 
       <Summary>[MyCustomAttribute]</Summary> 
      </Documentation> 
</Property> 

y reemplazar T4:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Con:

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty) 
{ 
    if(edmProperty.Documentation != null && string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
    #> 
    <#=edmProperty.Documentation.Summary#> 
<#+ 
    } 
    WriteProperty(Accessibility.ForProperty(edmProperty), 
        code.Escape(edmProperty.TypeUsage), 
        code.Escape(edmProperty), 
        code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
        code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

Y para Entity Framework 6, reemplace

public string Property(EdmProperty edmProperty) 
{ 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{0} {1} {2} {{ {3}get; {4}set; }}", 
     Accessibility.ForProperty(edmProperty), 
     _typeMapper.GetTypeName(edmProperty.TypeUsage), 
     _code.Escape(edmProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 
} 

con

public string Property(EdmProperty edmProperty) 
{ 
    var description = String.Empty; 
    bool isAttribute = false; 

    if(edmProperty.Documentation != null && 
     string.IsNullOrWhiteSpace(edmProperty.Documentation.Summary) == false) 
    { 
     string summary = edmProperty.Documentation.Summary; 
     if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']') 
     { 
      isAttribute = true; 
     } 

     if (isAttribute) 
     { 
      description = String.Format("\r\n\t{0}\r\n\t", summary); 
     } 
     else 
     { 
      description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t", 
       summary); 
     } 

    } 

    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     Accessibility.ForProperty(edmProperty), 
     _typeMapper.GetTypeName(edmProperty.TypeUsage), 
     _code.Escape(edmProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(edmProperty)), 
     description); 
} 

Advertencias:

  • espacios de nombres deben resolverse absolutamente.
  • Asume que los atributos comienzan con '[' y terminan con ']' - no hay otro error que compruebe
  • Si no se encuentra un parlante de apertura y cierre, el resumen de la propiedad del marco de la entidad se envuelve en un comentario de triple barra XML.
  • Intenta hacer coincidir la información de estilo de estudio visual predeterminada (realmente solo sangrías) que puede o no ser el caso para su proyecto. Esto incluye nuevas líneas.salida

muestra:

/// <summary> 
/// content type 
/// </summary> 
public System.Guid ContentType { get; set; } 

[System.ComponentModel.DisplayName("Last Modified")] 
public System.DateTime LastModified { get; set; } 
0

Además de la respuesta de BurnsBA, aplicar esto a las propiedades de navegación también, actualizar NavigationProperty() así:

public string NavigationProperty(NavigationProperty navProp) 
{ 
    var description = String.Empty; 
    if(navProp.Documentation != null && string.IsNullOrWhiteSpace(navProp.Documentation.Summary) == false) 
    { 
     string summary = navProp.Documentation.Summary; 
     if (!String.IsNullOrEmpty(summary) && summary.First() == '[' && summary.Last() == ']') 
     { 
      description = String.Format("\r\n\t{0}\r\n\t", summary); 
     } 
     else 
     { 
      description = String.Format("\r\n\t/// <summary>\r\n\t/// {0}\r\n\t/// </summary>\r\n\t", summary); 
     } 
    } 

    var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 
     navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 
     _code.Escape(navProp), 
     _code.SpaceAfter(Accessibility.ForGetter(navProp)), 
     _code.SpaceAfter(Accessibility.ForSetter(navProp)), 
     description); 
} 

Lo utilizo para añadir [Newtonsoft.Json.JsonIgnore] a mi propiedades.

Nota: Hay que añadir estos a <...>Model.tt y no <...>Model.Context.tt

Cuestiones relacionadas