Можно ли определить свойства в частичных классах, а затем пометить их атрибутами в другом частичном классе? - PullRequest
64 голосов
/ 24 сентября 2010

Можно ли сгенерировать файл с кодом, например, так:

public partial class A {
public string a {get; set;}
}

, а затем в другом файле:

public partial class A {
[Attribute("etc")]
public string a {get; set;}
}

Чтобы я мог создать класс, сгенерированный из базы данных, а затем использовать несгенерированный файл для его разметки?

Ответы [ 5 ]

63 голосов
/ 19 октября 2013

Вот решение, которое я использовал для таких случаев.Это полезно, когда у вас есть автоматически сгенерированные классы, которые вы хотите украсить атрибутами.Допустим, это автоматически сгенерированный класс:

public partial class UserProfile
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

И скажем, я хотел бы добавить атрибут, чтобы указать, что UserId является ключом.Затем я бы создал частичный класс в другом файле, например:

[Table("UserProfile")]
[MetadataType(typeof(UserProfileMetadata))]
public partial class UserProfile
{
    internal sealed class UserProfileMetadata
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
    }
}
29 голосов
/ 24 сентября 2010

Я видел нечто подобное в статье Скотта Гатри (ближе к концу) - хотя сам не пробовал. 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; }
}
2 голосов
/ 24 февраля 2017

Это мой ответ
различные файлы классов, или вы можете объединить метаданные в одном файле, но оставить пространство имен одинаковым, чтобы они могли видеть друг друга, очевидно.Обновите свою модель, например, добавьте больше столбцов, вам также необходимо обновить класс проекта.

--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
{
}
1 голос
/ 04 ноября 2017

Вам необходимо определить частичный класс для вашего A класса, как показано ниже:

using 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; }
}
0 голосов
/ 24 сентября 2010

Не как таковой;компилятор будет жаловаться, что член определен в нескольких частях.Однако, поскольку использование пользовательских атрибутов носит отражающий характер, вы можете определить класс «метаданных» и использовать его для хранения декораторов.

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...