Qual è questo il modo migliore per ottenere i nomi reali delle colonne dal mio POCO?
Domanda
Sto usando Petapoco Creare un elenco di oggetti generici che sono quindi legati a una gridview. Tuttavia, poiché i nomi delle colonne non sono nomi di proprietà validi, ottengono modifiche dal codice T4. Vorrei passare attraverso le colonne di Gridview e modificare il testo dell'intestazione per mostrare i nomi delle colonne reali. Qual è il modo migliore per ottenere gli attributi di colonna di una proprietà POCO quando ho semplicemente una rappresentazione di stringa del nome della proprietà?
Ad esempio, ho:
[ExplicitColumns]
public partial class SomeTable : DB.Record<SomeTable>
{
[Column("5F")]
public int _5F
{
get {return __5F;}
set {__5F = value;
MarkColumnModified("5F");}
}
int __5F;
}
Voglio una routine come:
public string GetRealColumn(string ObjectName, sting PropertyName)
In modo che: getRealColumn ("Somethable", "_5f") restituisce "5f"
Eventuali suggerimenti?
Soluzione
Puoi sempre usare la riflessione per ottenere l'attributo applicato alla proprietà, qualcosa sulla falsariga di:
public string GetRealColumn(string objectName, string propertyName)
{
//this can throw if invalid type names are used, or return null of there is no such type
Type t = Type.GetType(objectName);
//this will only find public instance properties, or return null if no such property is found
PropertyInfo pi = t.GetProperty(propertyName);
//this returns an array of the applied attributes (will be 0-length if no attributes are applied
object[] attributes = pi.GetCustomAttributes(typeof(ColumnAttribute));
ColumnAttribute ca = (ColumnAttribute) attributes[0];
return ca.Name;
}
Per motivi di brevità e chiarezza ho omesso il controllo degli errori, dovresti aggiungerne alcuni per assicurarti che non fallisca in fase di esecuzione. Questo non è codice di qualità della produzione.
Anche la riflessione tende ad essere lenta, quindi è meglio memorizzare nella cache i risultati.
Altri suggerimenti
Bene, se hai intenzione di farlo molto, potresti fare qualcosa del genere:
- Crea un'interfaccia di base da cui tutte le tue classi Petapoco erezzeranno.
- Crea una classe parziale da "qualche povera" che eredita l'interfaccia.
- Definire un'estensione statica che consente di fornire il nome della colonna. Ciò dovrebbe restituire il nome "colonnellabute" definito quando impostato, altrimenti restituire il nome definito sulla classe.
1 & 2
namespace Example {
//Used to make sure the extension helper shows when we want it to. This might be a repository....??
public interface IBaseTable { }
//Partial class must exist in the same namespace
public partial class SomeTable : IBaseTable { }
}
3
public static class PetaPocoExtensions {
public static string ColumnDisplayName(this IBaseTable table, string columnName) {
var attr = table.GetType().GetProperty(columnName).GetCustomAttributes(typeof(ColumnAttribute), true);
return (attr != null && attr.Count() > 0) ? ((ColumnAttribute)attr[0]).Name : columnName;
}
}
Ora lo chiami così:
SomeTable table = new SomeTable();
var columnName = table.ColumnDisplayName("_5F");