Ich verwende das ADO.Net-Entitätsdatenmodell, das eine Verbindung zu einer SQL Server-Datenbank herstellt, um Entitätsklassen zu generieren.
Ich erstelle Teilklassen für die generierten Klassen mit diesem Attribut:
[MetadataType(typeof(Employee))]
um DataAnnotations
auf die Felder zu setzen. Daher entferne ich alle Felder aus der generierten Klasse ( .g.cs
) und verschiebe sie in die andere .g.cs
und lege die Datenanmerkungen in diese Klasse.
Das Problem tritt auf, wenn ich das Modell aus der Datenbank aktualisiere (unabhängig davon, ob ich zuerst vorhandene Tabellen aus dem Entitätsdatenmodell lösche oder das Modell nur aktualisiere, wird der generierte g.cs
generiert. Und ich muss die g.cs
erneut manuell aus g.cs
löschen Klassen, weil sie bereits in anderen Teilklassen (in der durch das MetadataType
Attribut angegebenen Klasse) existieren.
Ist es möglich, dass der generierte Code bei der Aktualisierung des Modells nicht neu generiert wird und ich den Code für bestimmte Tabellen / Klassen bei Bedarf manuell neu generieren kann?
[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; } }
}
und hier ist die g.cs
Datei (generierte Datei)
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; }
}
Sie verwenden das MetadataTypeAttribute
falsch. Sie sollten eine separate Klasse für die Anmerkungen erstellen.
Ich mache es zum Beispiel mit einer privaten inneren Klasse:
[MetadataType(typeof(Table1MetaData))]
public partial class Table1
{
private class Table1MetaData
{
[MaxLength(20)]
public string Foo { get; set; }
}
}
Wichtig ist, dass der Eigenschaftsname der MetaData-Klasse derselbe wie der partielle ist. Also oben, ist das Gleiche wie:
public partial class Table1
{
[MaxLength(20)]
public string Foo { get; set; }
}
Du solltest für den ersten gehen.
Da die Klasse partiell ist, gilt Folgendes:
public string first_name { get; set; }
public string last_name { get; set; }
[Display(Name="Name")]
public string FullName { get { return first_name + " " + last_name; }
Sie können und sollten nur Ihre Immobilie schreiben:
[Display(Name="Name")]
public string FullName { get { return first_name + " " + last_name; }
Fazit:
MetadataType
nur zum Hinzufügen von DataAnnotation-Attributen zu generierten Eigenschaften. Wenn Sie sich jedoch nicht wohl fühlen, wie Entity Framework Code generiert, können Sie die T4-Vorlage bearbeiten. Es ist hinter der edmx-Datei versteckt (einfach erweitern).
Du hast nicht gefragt, aber du wirst früher oder später kommen:
Wenn Sie über benutzerdefinierte Attribute verfügen und diese erhalten möchten, müssen Sie auch die Metadaten überprüfen:
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;
}
Eine MVC
Alternative hierzu wäre ein benutzerdefinierter DataAnnotationsModelMetadataProvider
.