Domanda

Sto usando .NET 4.0, C# 4.0 in Visual Studio 2012 con codice First and Entity Framework.

Ho una serie di classi che voglio utilizzare come base per vari rapporti. I dati per i report sono tenuti in un database SQL. Una classe di esempio è:

public class DocumentTrackerChaseReport
{
    public int DocumentTrackerChaseReportID { get; set; }
    public int CaseID { get; set; }
    public int DocumentID { get; set; }

    [Description("Case ID")]
    public String CaseIdentifier { get; set; }
    [Description("Document type")]
    public String DocumentCategory { get; set; }
    [Description("Contact")]
    public String ContactName { get; set; }
    [Description("Phone number")]
    public String ContactPhoneNumber { get; set; }
    [Description("email address")]
    public String ContactEmail { get; set; }

    public TrackingActionType TrackingActionType { get; set; }
}

Gli attributi di descrizione agiscono sia come intestazioni per il rapporto sia per indicare quali proprietà devono essere escluse dal rapporto.

Ho un metodo per estrarre le intestazioni come array di stringhe da questo domanda

Posso anche generare un metodo che controlla se un campo/proprietà ha un attributo di descrizione.

L'ingrediente chiave che mi manca è un modo semplice e generico per generare ogni riga del rapporto che omette i campi che non hanno questo attributo. Posso iterare attraverso tutti i campi usando la riflessione e il controllo dell'attributo per ogni riga del rapporto, ma sembra a lungo e fico.

C'è una soluzione elegante a questo?

È stato utile?

Soluzione

Puoi pre-cache i nomi delle proprietà a cui sei interessato (cioè quelli con l'attributo Descrizione) e quindi utilizzare quelli per prendere solo i valori che ti interessa.

Ho violato un rapido esempio di questo, non è il codice più robusto, ma mostra l'idea generale (fa molte ipotesi sull'ordinamento) e ha recuperato gli attributi solo una volta.

(Modifica: realizzato che dovevamo chiamare GetProperties solo una volta per tutto).

var whitelist = typeof (DocumentTrackerChaseReport)
    .GetProperties()
    .Where(x => Attribute.IsDefined(x, typeof (DescriptionAttribute)));

var rows = things.Select(x => whitelist.Select(y => y.GetValue(x) ?? ""));

Questo ti darà un IEnumerable<IEnumerable<object>>, o in altre parole, un elenco di righe e per ogni riga, un elenco di colonne (con il valore di ciascuna colonna che è un oggetto).

Potresti quindi iterare attraverso questo come segue (codice pseudo)

foreach (var header in whitelist) {
    // print column of header row
}

foreach (var row in rows) {
    foreach (var col in row) {
        // print an individual cell
    }
    // break for a new row
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top