Pergunta

Estou usando o .NET 4.0, C# 4.0 no Visual Studio 2012 com o Code First e Entity Framework.

Eu tenho um conjunto de classes que quero usar como base para vários relatórios. Os dados dos relatórios são mantidos em um banco de dados SQL. Uma classe de exemplo é:

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

Os atributos da descrição atuam como cabeçalhos para o relatório e também para indicar quais propriedades devem ser excluídas do relatório.

Eu tenho um método para extrair os cabeçalhos como uma matriz de string de isto pergunta

Também posso gerar um método que verifica se um campo/propriedade tem um atributo de descrição.

O principal ingrediente que estou perdendo é uma maneira direta e genérica de gerar cada linha do relatório que omitindo os campos que não têm esse atributo. Eu posso iterar em todos os campos usando reflexão e verificação do atributo para cada linha do relatório, mas isso parece há muito tempo.

Existe uma solução elegante para isso?

Foi útil?

Solução

Você pode pré-cache os nomes das propriedades em que você está interessado (ou seja, aqueles com o atributo de descrição) e, em seguida, usá-los para pegar apenas os valores em que você está interessado.

Eu invadi um exemplo rápido disso, não é o código mais robusto, mas mostra a ideia geral (faz muitas suposições sobre o pedido) e apenas buscou os atributos uma vez.

(Editar: percebi que precisávamos apenas chamar GetProperties uma vez para tudo).

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

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

Isso lhe dará um IEnumerable<IEnumerable<object>>, ou em outras palavras, uma lista de linhas e para cada linha, uma lista de colunas (com o valor de cada coluna sendo um objeto).

Você pode então iterar com isso da seguinte maneira (código 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
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top