Sto usando ADO.Net Entity Data Model che si connette a un database SQL Server per generare classi di entità.
Sto creando delle classi parziali per le classi generate con questo attributo:
[MetadataType(typeof(Employee))]
mettere DataAnnotations
sui campi. Quindi rimuovo tutti i campi dalla classe generata ( .g.cs
) e li sposto all'altra classe parziale e inserisco le annotazioni dei dati in questa classe.
Il problema si verifica ogni volta che aggiorno il modello dal database (indipendentemente dal fatto che prima elimini le tabelle esistenti dal modello dei dati dell'entità o semplicemente aggiorni il modello, il codice delle classi generate venga rigenerato. E devo nuovamente cancellare manualmente gli attributi del campo da g.cs
classi perché esistono già in altre classi parziali (nella classe specificata dall'attributo MetadataType
).
È possibile che quando aggiorno il modello il codice generato non venga rigenerato e, se necessario, posso rigenerare manualmente il codice per una determinata tabella / classe?
[MetadataType(typeof(Employee))]
public partial class Employee
{
public string badge_no { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
[Display(Name="Name")]
public string FullName { get { return first_name + " " + last_name; } }
[Display(Name = "Badge-Name")]
public string NameAndBadge { get { return badge_no + " " + FullName; } }
}
ed ecco il file g.cs
(file generato)
public partial class Employee
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Employee()
{
this.EmpWrkDesignations = new HashSet<EmpWrkDesignation>();
}
public int id { get; set; }
//public string badge_no { get; set; }
//public string first_name { get; set; }
//public string last_name { get; set; }
public System.DateTime row_added_date { get; set; }
public Nullable<System.DateTime> row_changed_date { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<EmpWrkDesignation> EmpWrkDesignations { get; set; }
}
Stai utilizzando il MetadataTypeAttribute
errato. Dovresti creare una classe separata per le annotazioni.
Lo faccio con una classe interna privata per esempio:
[MetadataType(typeof(Table1MetaData))]
public partial class Table1
{
private class Table1MetaData
{
[MaxLength(20)]
public string Foo { get; set; }
}
}
La cosa importante è che il nome della proprietà della classe MetaData è uguale a quello parziale. Così sopra, è lo stesso di:
public partial class Table1
{
[MaxLength(20)]
public string Foo { get; set; }
}
Dovresti andare per il primo.
Inoltre, poiché la classe è parziale, anziché:
public string first_name { get; set; }
public string last_name { get; set; }
[Display(Name="Name")]
public string FullName { get { return first_name + " " + last_name; }
Puoi e dovresti scrivere solo la tua proprietà:
[Display(Name="Name")]
public string FullName { get { return first_name + " " + last_name; }
Conclusione:
MetadataType
solo per aggiungere gli attributi DataAnnotation alle proprietà generate . Detto questo, se non ti senti a tuo agio nel modo in cui Entity Framework genera codice, puoi modificare il modello T4. È nascosto dietro il file edmx (basta espanderlo).
Non hai chiesto, ma ti capiterà prima o poi:
Un trabocchetto è che se hai attributi personalizzati e vuoi ottenerli, devi controllare anche i metadati:
public static TAttribute GetAttributeOrUseMetadata<TAttribute>(this PropertyInfo element, bool inherit = false) where TAttribute : System.Attribute
{
//Find normal attribute
var attribute = element.GetCustomAttribute<TAttribute>(inherit);
if (attribute != null)
{
return attribute;
}
//Find via MetadataTypeAttribute
if (element.DeclaringType != null)
{
var metadataType = element.DeclaringType.GetCustomAttribute<MetadataTypeAttribute>(inherit);
var metadataPropertyInfo = metadataType?.MetadataClassType.GetProperty(element.Name);
return metadataPropertyInfo?.GetCustomAttribute<TAttribute>();
}
return null;
}
Un'alternativa MVC
per questo sarebbe un DataAnnotationsModelMetadataProvider
personalizzato.