Qual è questo il modo migliore per ottenere i nomi reali delle colonne dal mio POCO?

StackOverflow https://stackoverflow.com/questions/8891804

  •  29-10-2019
  •  | 
  •  

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?

È stato utile?

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:

  1. Crea un'interfaccia di base da cui tutte le tue classi Petapoco erezzeranno.
  2. Crea una classe parziale da "qualche povera" che eredita l'interfaccia.
  3. 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");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top