5

目標:

私たちのアプリケーションは、複数のタイプ (Person、PersonSite(ICollection)、Site など) を使用して構築されています。これらのクラスには関係があるため、これらのクラスを選択しました。私たちがやりたいことは、最初のタイプ (Person) からいくつかのプロパティを Excel テーブルにエクスポートし、次に同じ Excel ファイル内の 2 番目のタイプ (PersonSite) からいくつかの他のプロパティを同じ Excel ファイル内の新しいテーブルにエクスポートできるようにすることです。シート。

結果は次のようになります。

_________________ ________________________ ________________
| | | | | | | | | | | |
|個人のプロパティ| | | 個人サイトのプロパティ | |サイトのプロパティ |
|_________________| |________________________| |________________|
| | 名前の人 1 | |アイテム 1 の関係タイプ| | | アイテムの名前 1|
|_________________| |________________________| |________________|
                    |項目 2 の関係タイプ| | | アイテム 2 の名前|
                    |________________________| |________________|
                    |項目 3 の関係タイプ| | | 項目 3 の名前|
                    |________________________| |________________|
 _________________ ________________________ ________________
| | 名前の人 2 | |アイテム 1 の関係タイプ| | | アイテムの名前 1|
|_________________| |________________________| |________________|
                    |項目 2 の関係タイプ| | | アイテムの名前 1|
                    |________________________| |________________|

したがって、リストに含まれるすべての PersonSite に対して、Person のテーブルの直後に挿入されるテーブルを作成したいと考えています。

したがって、これは Person クラス (クラスのサブセット) の外観です。

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

PersonSite クラス (サブセット) :

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

サイト クラス (サブセット) :

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

そこで、式を使用してエクスポートする必要があるプロパティを取得する CSVExporter クラスを作成することにしました。

これは、これを実装する必要があるスキームです。

                    
                            ____
                           | | |0..*
 ______________ __|____|______ 1..* ________________
| | CSV エクスポーター |________| CSV テーブル (T)|__________| CSV 列 (T)|
|______________| |______________| |________________|
                               | |
                               |1..*
                         ______|________
                        | | CSV 行 (T) |
                        |________________|

そのため、CSVTable は IObject であるジェネリック型を使用します (さまざまなクラスで使用されているように)。

テーブルは複数のテーブルを持つことができます (たとえば、Person テーブルには PersonSite テーブルがあり、PersonSite テーブルには Site テーブルがあります)。ただし、さまざまなクラスをナビゲートするため、使用される型は異なります (これらのクラスには関係が必要です)。

サブテーブルをテーブルに追加するときは、メイン項目から正しいタイプの項目を取得する式を提供する必要があります (Person => Person.PersonSite)

そのため、テーブルに対して次のコードを記述しました。

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

最後に、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;
    }
}

誰もそのようなことをしたことがありますか?それとも間違った道に向かっているのでしょうか? これが適切なパスであると思われる場合、リンク (関係) 式を作成し、それを使用して最後の呼び出しで使用する正しいアイテムを取得するにはどうすればよいでしょうか?

4

1 に答える 1

0

遅れて申し訳ありません、

最終的に、次のように動作するようになりました。

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

これにより、サブテーブルのテンプレートが適用されます。

これが他の人に役立つことを願っています。

于 2012-03-26T08:32:02.293 に答える