Czy istnieje sposób na wygenerowanie pliku kodu w następujący sposób:
public partial class A {
public string a {get; set;}
}
a potem w innym pliku:
public partial class A {
[Attribute("etc")]
public string a {get; set;}
}
Więc mogę mieć klasę wygenerowaną z bazy danych, a następnie użyć nie wygenerowanego pliku, aby ją oznaczyć?
c#
attributes
code-generation
partial-classes
Chris McCall
źródło
źródło
Odpowiedzi:
Widziałem coś takiego zrobionego w artykule Scotta Guthrie (pod koniec) - chociaż sam tego nie próbowałem.
http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx
[MetadataType(typeof(Person_Validation))] public partial class Person { // Partial class compiled with code produced by VS designer } [Bind(Exclude="ID")] public class Person_Validation { [Required(ErrorMessage = "First Name Required")] [StringLength(50, ErrorMessage = "Must be under 50 characters")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name Required")] [StringLength(50, ErrorMessage = "Must be under 50 characters")] public string LastName { get; set; } [Required(ErrorMessage = "Age Required")] [Range(0, 120, ErrorMessage = "Age must be between 0 and 120")] public int Age { get; set; } [Required(ErrorMessage = "Email Required")] [Email(ErrorMessage = "Not a valid email")] public string Email { get; set; } }
źródło
[MetaDataType ...
zostanie wyczyszczony za każdym razem, gdy projektant uruchomi sięMetadataType
atrybutu w pliku wygenerowanym przez projektanta, ale umieszczasz go w innym pliku, w którymPerson
zdefiniowana jest klasa częściowa .Oto rozwiązanie, którego używałem w takich przypadkach. Jest to przydatne, gdy masz automatycznie generowane klasy, które chcesz ozdobić atrybutami. Powiedzmy, że to jest klasa wygenerowana automatycznie:
public partial class UserProfile { public int UserId { get; set; } public string UserName { get; set; } public string Firstname { get; set; } public string Lastname { get; set; } }
Powiedzmy, że chciałbym dodać atrybut określający, że UserId jest kluczem. Utworzyłbym wtedy klasę częściową w innym pliku, takim jak ten:
[Table("UserProfile")] [MetadataType(typeof(UserProfileMetadata))] public partial class UserProfile { internal sealed class UserProfileMetadata { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } } }
źródło
MetadataType
atrybutem. Dobra robota!UserProfile
?MetadataType
nie istnieje w .NET CoreModelMetadataType
To jest moja odpowiedź na
różne pliki klas lub możesz połączyć metadane w tym samym pliku, ale zachowaj przestrzeń nazw taką samą ... więc oczywiście mogą się widzieć.
Pamiętaj, że podczas aktualizowania modelu, np. dodawania kolejnych kolumn, musisz również zaktualizować klasę projektu.
--your model class public partial class A { public string a {get; set;} } --your project class public class Ametadata { [Attribute("etc")] public string a {get; set;} } [MetadataType(typeof(Ametadata))] public partial class A { }
źródło
Musisz zdefiniować częściową klasę dla swojej
A
klasy, tak jak w poniższym przykładzieusing System.ComponentModel.DataAnnotations; // your auto-generated partial class public partial class A { public string MyProp { get; set; } } [MetadataType(typeof(AMetaData))] public partial class A { } public class AMetaData { [System.ComponentModel.DefaultValue(0)] public string MyProp { get; set; } }
źródło
Nie jako takie; kompilator będzie narzekał, że element członkowski jest zdefiniowany w wielu częściach. Ponieważ jednak użycie atrybutów niestandardowych ma charakter refleksyjny, można zdefiniować klasę „metadanych” i użyć jej do umieszczenia dekoratorów.
public class A { public string MyString; } public class AMeta { [TheAttribute("etc")] public object MyString; } ... var myA = new A(); var metaType = Type.GetType(myA.GetType().Name + "Meta"); var attributesOfMyString = metaType.GetMember("MyString").GetCustomAttributes();
źródło