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

Есть ли способ, которым я могу иметь файл сгенерированного кода, например, так:

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

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

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

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

 Chris McCall23 сент. 2010 г., 23:29
@snemarch: только определения свойств, я планирую делать любой другой код вручную.
 snemarch23 сент. 2010 г., 22:48
Сколько "генерируется из базы данных"? Только определения свойств или код?
 CyberNinja24 февр. 2017 г., 17:29
да, это возможно, но с использованием метаданных, тогда другие частичные наследуют эти метаданные
 Kirk Woll23 сент. 2010 г., 22:51
Короткий ответ, нет. Длинный ответ, дупstackoverflow.com/questions/456624/....
 snemarch23 сент. 2010 г., 23:44
Не могли бы вы сделать с разделением интерфейса + реализации вместо частичного класса? Сгенерируйте интерфейс из базы данных, внедрите (и добавьте атрибуты) в реализацию.

Ответы на вопрос(5)

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

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();
 Kirk Woll23 сент. 2010 г., 23:01
Как часто актер, который добавляет атрибуты к своим свойствам, также является человеком, потребляющим их, и поэтому будет знать, что нужно искать магические классы "Мета"?
 KeithS23 сент. 2010 г., 23:08
Довольно часто по моему опыту. Это не будет работать для существующего аспектно-ориентированного фреймворка, но если вы украшаете свой домен, скажем, с помощью пользовательских атрибутов проверки, вы ищете их и можете определить, где. Моя команда сделала именно это на одном из наших проектов. Основным недостатком не ищет другой класс; при разработке он поддерживает два параллельных класса, один функциональный, другой декоративный. Это было бы проблемой и для частичных классов, если бы вы могли определить частичные поля / свойства в первую очередь.
Решение Вопроса

Я видел нечто подобное в статье Скотта Гатри (ближе к концу) - хотя сам не пробовал.
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; }
}
 user58639927 нояб. 2016 г., 08:05
Это решение НЕ решает проблему. Почему мы смотрим, чтобы украсить элементы в другом файле? Потому что класс ЗАПИСАН каждый раз при запуске дизайнера. Таким образом, ваш атрибут[MetaDataType ... будет очищаться при каждом запуске дизайнера
 CyberNinja24 февр. 2017 г., 17:29
проблема с этим решением в том, что класс должен быть частичным
 Kirk Woll23 сент. 2010 г., 23:09
Этот ответ заслуживает упоминания, но он не является общим решением вопроса, поставленного ФП. Потребители атрибутов все еще должны знать, чтобы искать класс метаданных - то есть эти атрибутыне должен быть возвращен Attribute.GetCustomAttribute (...). (К счастью для многих вариантов использования, пользователи пишут MS, и в определенных ситуациях это будет работать.)
 Dan Dumitru28 нояб. 2016 г., 13:36
@Desolator - идея в том, что вы не ставитеMetadataType атрибут в файле, сгенерированном дизайнером, вы помещаете его в другой файл, где частичный классPerson определено.

Вам нужно определить частичный класс для вашего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; }
}


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

имейте в виду, что при обновлении модели, например, при добавлении столбцов, вам также необходимо обновить класс проекта.

--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
{
}

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

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; }
    }
}
 frankyjuang31 июл. 2019 г., 08:46
ядро .net используетModelMetadataType
 Brent8124 авг. 2017 г., 07:58
MetadataType можно использовать только для класса, что делать, если я хочу сделать со Struct?
 Dave16 авг. 2019 г., 13:18
Есть ли вариант для .NET Core, который не связан с MVC? Я пишу консольное приложение для зеркального отображения данных из унаследованной корпоративной системы в базу данных SQL и хочу сделать что-то похожее на вышеперечисленное, но для этой функциональности мне нужно включить множество нежелательных пакетов MVC.
 WoIIe05 мар. 2019 г., 18:35
MetadataType не существует в .NET Core
 Pflugs09 янв. 2016 г., 12:45
Отличное решение. Я знал, что вы можете украсить частичный класс атрибутами в нескольких файлах и даже добавить интерфейсы и унаследованный класс к его объявлению, но я не устанавливал связь сMetadataType приписывать. Отлично сработано!
 Gašper Sladič20 мая 2015 г., 12:23
Работал как шарм! Спасибо!!!
 Botis28 мар. 2017 г., 12:31
Что делать, если я хочу добавить атрибут в конструкторUserProfile?

Ваш ответ на вопрос