Question

Objectif:

Notre application est construit en utilisant plusieurs types (par exemple personne, PersonSite (ICollection), site - je choisis ces classes parce qu'ils ont une relation). Ce que nous voulons faire est d'être en mesure d'exporter certaines propriétés du premier type (personne) dans un tableau Excel, puis exporter d'autres propriétés du deuxième type (PersonSite) dans le même fichier Excel, mais dans une nouvelle table sur la même feuille.

Le résultat devrait ressembler à ceci:

 _________________   ________________________   ________________
|                 | |                        | |                |
|PERSON PROPERTIES| | PERSONSITE PROPERTIES  | |SITE PROPERTIES |
|_________________| |________________________| |________________|
|  Name Person 1  | |Relation type for item 1| | Name for item 1|
|_________________| |________________________| |________________|
                    |Relation type for item 2| | Name for item 2|
                    |________________________| |________________|
                    |Relation type for item 3| | Name for item 3|
                    |________________________| |________________|
 _________________   ________________________   ________________
|  Name Person 2  | |Relation type for item 1| | Name for item 1|
|_________________| |________________________| |________________|
                    |Relation type for item 2| | Name for item 1|
                    |________________________| |________________|

Ainsi, pour chaque PersonSite contenu dans la liste, nous aimerions créer une table qui sera insérée juste après la table de la personne.

Alors voilà comment regarder la classe personne (sous-ensemble de la classe):

public class Person : IObject
{
   public ICollection<PersonSite> PersonSites {get;set;}
}

Maintenant, la classe PersonSite (sous-ensemble):

public class PersonSite : IObject
{
   public Person Person {get;set;}
   public Site Site {get;set;}
   public RelationType RelationType {get;set;}
}

La classe du site (sous-ensemble):

public class Site : IObject
{
   public ICollection<PersonSite> PersonSites {get;set;}
}

Nous avons donc décidé d'écrire une classe CSVExporter que les expressions d'utiliser pour récupérer les propriétés qui doivent être exportés.

Ceci est le schéma que nous devons mettre en œuvre ceci:

                    
                            ____
                           |    |0..*
 ______________          __|____|______       1..* _______________
| CSV EXPORTER |________| CSV TABLE (T)|__________| CSV COLUMN (T)|
|______________|        |______________|          |_______________|
                               |
                               |1..*
                         ______|________
                        | CSV ROWS (T)  |
                        |_______________|

Ainsi, l'utilisation CSVTable un type générique qui est IObject (utilisé dans les différentes classes).

Une table peut avoir plusieurs tables (par exemple La table personne a une table et une table PersonSite PersonSite dispose d'une table de site). Mais le type utilisé est différent puisque nous naviguons à travers les différentes classes (ces classes doivent avoir une relation).

Lors de l'ajout d'un sous-table à une table que nous devrions fournir en expression qui saisira les éléments du type correct à partir des éléments principaux (personne => Person.PersonSite)

Nous avons donc écrit le morceau de code suivant pour la table:

public class CSVExportTable<T>
    where T : IObject
{

    private Matrix<string> Matrix { get; set; }
    private ICollection<CSVExportTableColumn<T>> Columns { get; set; }
    private ICollection<CSVExportTableRow<T>> Rows { get; set; }
    private ICollection<CSVExportTable<IObject>> SubTables { get; set; }
    private Expression<Func<T, object>> Link { get; set; }


    public CSVExportTable()
    {
        this.Matrix = new Matrix<string>();
        this.Columns = new List<CSVExportTableColumn<T>>();
        this.SubTables = new List<CSVExportTable<IObject>>();
        this.Rows = new List<CSVExportTableRow<T>>();
    }

    public CSVExportTable<R> AddSubTable<R>(Expression<Func<T, object>> link) where R : IObject
    {
        /* This is where we create the link between the main table items and the subtable items (= where we retreive Person => Person.PersonSites as an ICollection<R> since the subtable has a different type (T != R but they have the same interface(IObject))*/
    }

    public void AddColumn(Expression<Func<T, object>> exportProperty)
    {
        this.Columns.Add(new CSVExportTableColumn<T>(exportProperty));
    }

    public Matrix<string> GenerateMatrix()
    {
        int rowIndex= 0;
        foreach (CSVExportTableRow<T> row in this.Rows)
        {
            int columnIndex = 0;
            foreach (CSVExportTableColumn<T> column in this.Columns)
            {
                this.Matrix = this.Matrix.AddValue(rowIndex, columnIndex, ((string)column.ExportProperty.Compile().DynamicInvoke(row.Item)));
                columnIndex++;
            }
            rowIndex++;
        }
        return this.Matrix;
    }

    public Matrix<string> ApplyTemplate(ICollection<T> items)
    {
        // Generate rows
        foreach (T item in items)
        {
            this.Rows.Add(new CSVExportTableRow<T>(item));
        }
        // Instantiate the matrix
        Matrix<string> matrix = new Matrix<string>();

        // Generate matrix for every row
        foreach (var row in this.Rows)
        {
            matrix = GenerateMatrix();
            // Generate matrix for every sub table
            foreach (var subTable in this.SubTables)
            {
                // This it where we should call ApplyTemplate for the current subTable with the elements that the link expression gave us(ICollection).
            }
        }
        return matrix;
    }
}

Et est enfin là la classe CSVExportTableColumn:

public class CSVExportTableColumn<T> where T : IObject
{
    public Expression<Func<T, object>> ExportProperty { get; set; }

    public CSVExportTableColumn(Expression<Func<T, object>> exportProperty)
    {
        this.ExportProperty = exportProperty;
    }
}

Quelqu'un at-il jamais fait quelque chose comme ça? Ou sommes-nous dirigeons vers le mauvais chemin? Si cela semble être un bon chemin, comment pouvons-nous créer le lien (relation) l'expression et l'utiliser pour récupérer les éléments corrects à utiliser le dernier appel?

Était-ce utile?

La solution

Désolé pour le retard,

Alors finalement, nous l'avons eu à travailler comme ceci:

public Matrix<string> ApplyTemplate(object items)
    {
        ICollection<T> castedItems = new List<T>();
        // Cast items as a List<T>
        if (items is List<T>)
        {
            castedItems = (ICollection<T>)items;
        }
        else if (items is HashSet<T>)
        {
            castedItems = ((HashSet<T>)items).ToList();
        }
        // Generate rows
        foreach (T item in castedItems)
        {
            this.Rows.Add(new CSVExportTableRow<T>(item));
        }
        // Instantiate the matrix
        Matrix<string> matrix = new Matrix<string>();

        // Generate matrix for every row
        foreach (var row in this.Rows)
        {
            matrix = GenerateMatrix();
            // Generate matrix for every sub table
            foreach (var subTable in this.SubTables)
            {
                matrix = matrix.AddMatrix(subTable.ApplyTemplate(this.Link.Compile().DynamicInvoke(row.Item)));
            }
        }
        return matrix;
    }

appliquera le modèle pour toutes les tables sous.

Espérons que cela peut être utile pour les autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top