使用扩展方法检索 C# 属性数据

Retrieve C# Attribute Data With Extension Method

正在寻找一种方法来使用扩展方法在我的数据层中的 class(许多不同类型)上检索 属性 的属性数据...

最终目标是看到这里的方法并能够访问属性:

我希望能够做类似(非工作代码)的事情:

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

属性分配给 class 属性 是这样的:

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

我创建了一个扩展方法来从 'ColumnSchemaAttribute'

中检索 'SchemaDetails' 对象
public class AttributeExtensions
{
    public static SchemaDetails GetSchemaDetails(Type T)
    {
        ColumnSchemaAttribute csa = (ColumnSchemaAttribute)Attribute.GetCustomAttribute(T, typeof(ColumnSchemaAttribute));
        return csa.SchemaDetails;
    }
}

批量 'ColumnSchemaAttribute' 列的 returns 数据库架构详细信息

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

非常感谢任何有关执行此操作的方法或替代方法的帮助。

为了获得任何 属性 属性,您需要检索 属性 信息而不是类型,一种方法是使用表达式,检索 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);
    }