Получить данные атрибута С# с помощью метода расширения

Ищете способ получить данные атрибута для свойства в классе (много разных типов) в моем слое данных с помощью метода расширения...

Конечная цель — увидеть метод здесь и получить доступ к свойствам:

Получить данные атрибута С# с помощью метода расширения

Я ожидаю, что смогу сделать что-то вроде (нерабочий код):

Customer c = new Customer();
int mcl = c.CustNo.GetSchemaDetails().MaxCharLength;

Атрибут присваивается свойству класса как таковому:

public class Customer
{
    [ColumnSchema("Customer", "CUST_NO")] 
    public string CustNo { get; set; }
    //...
}

Я создал метод расширения для извлечения объекта SchemaDetails из атрибута ColumnSchemaAttribute.

public class AttributeExtensions
{
    public static SchemaDetails GetSchemaDetails(Type T)
    {
        ColumnSchemaAttribute csa = (ColumnSchemaAttribute)Attribute.GetCustomAttribute(T, typeof(ColumnSchemaAttribute));
        return csa.SchemaDetails;
    }
}

Основная часть «ColumnSchemaAttribute», которая возвращает сведения о схеме базы данных для столбца.

public class ColumnSchemaAttribute : System.Attribute
{
    private string tableName, columnName;
    
    public ColumnSchemaAttribute(string TableName, string ColumnName)
    {
        tableName = TableName;
        columnName = ColumnName;           
    }
    
    private SchemaDetails schemaDetails;
    public SchemaDetails SchemaDetails
    {
        get
        {
            if (schemaDetails == null) { schemaDetails = getSchemaDetails(); }
            return schemaDetails;
        }
    }
    
    private SchemaDetails getSchemaDetails()
    {
        SchemaDetails sd = null;
    
        string sql =
                   @"
                        SELECT * FROM INFORMATION_SCHEMA.COLUMNS c 
                        LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON ccu.COLUMN_NAME = c.COLUMN_NAME and ccu.TABLE_NAME = c.TABLE_NAME
                        LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc ON tc.CONSTRAINT_NAME = ccu.CONSTRAINT_NAME and tc.TABLE_NAME = ccu.TABLE_NAME
                        WHERE c.TABLE_NAME = @TableName and c.COLUMN_NAME = @ColumnName
                    ";
    
        try
        {
            using (SqlConnection sqlConnection = new SqlConnection(Helper.GetConnectionString()))
            {
                sqlConnection.Open();
                using (SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection))
                        {
                    sqlCommand.CommandType = CommandType.Text;
                    sqlCommand.Parameters.Add("@TableName", SqlDbType.NVarChar, -1).Value = tableName;
                    sqlCommand.Parameters.Add("@ColumnName", SqlDbType.NVarChar, -1).Value = columnName;
    
                    SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
                    while (sqlDataReader.Read())
                    {
                        sd = readData(sqlDataReader);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new System.ArgumentException(ex.Message);
        }
  
        return sd;
    }
}

Любая помощь относительно способа сделать это или альтернативный подход очень ценится.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
28
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы получить какой-либо атрибут свойства, вам нужно получить информацию о свойстве, а не о типе, один из способов сделать это — использовать выражения, следующим шагом после получения значения экземпляра SchemaDetails будет получение из него некоторого значения свойства:

public static class AttributeExtensions
{
    public static SchemaDetails GetSchemaDetails<T>(this T _, Expression<Func<T, object>> propertyAccessorExpression)
    {
        if (propertyAccessorExpression.Body is MemberExpression memberExpression)
        {
            if (memberExpression.Member is PropertyInfo propertyInfo)
            {
                var attribute = propertyInfo.GetCustomAttribute<ColumnSchemaAttribute>();

                if (attribute != null)
                {
                    return attribute.SchemaDetails;
                }
            }
        }

        return default;
    }
}

использование:

    public static void Main()
    {
        var customer = new Customer();
        var length = customer
            .GetSchemaDetailsFor(x => x.CustNo)
            .MaxCharLength;

        Console.WriteLine(length);
    }

Другие вопросы по теме