テーブルを使用してCSVへの一般的なエクスポート
-
25-10-2019 - |
質問
目標:
当社のアプリケーションは、複数のタイプ(Person、PersonSite(Icollection)、Site -これらのクラスが関係があるために選択しました)を使用して構築されています。私たちがやりたいのは、Excelテーブルで最初のタイプ(人)からいくつかのプロパティをエクスポートし、同じExcelファイル内の2番目のタイプ(PersonSite)から他のプロパティをエクスポートできるようにすることです。シート。
結果は次のようになります。
_________________ ________________________ ________________ | | | | | | |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| |________________________| |________________|
したがって、リストに含まれるすべての人物について、私たちは、人のテーブルの直後に挿入されるテーブルを作成したいと思います。
したがって、これが人クラス(クラスのサブセット)をどのように見えるかです:
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 EXPORTER |________| CSV TABLE (T)|__________| CSV COLUMN (T)| |______________| |______________| |_______________| | |1..* ______|________ | CSV ROWS (T) | |_______________|
したがって、csvtableはiobjectの一般的なタイプを使用します(異なるクラスで使用されています)。
テーブルには複数のテーブルを持つことができます(例:PersonSiteテーブルにはPersonSiteテーブルがあり、PersonSiteテーブルにはサイトテーブルがあります)。ただし、使用されるタイプは異なります。さまざまなクラスをナビゲートするためです(これらのクラスには関係がある必要があります)。
テーブルにサブテーブルを追加するときは、メインアイテムから正しいタイプのアイテムをつかむEN表現を提供する必要があります(person => personsonsite)
そこで、テーブルに次のコードを書きました。
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;
}
}
誰かがそのようなことをしたことがありますか?それとも私たちは間違った道に向かっていますか?これが良いパスであると思われる場合、リンク(関係)式を作成し、それを使用して最後の呼び出しで使用する正しいアイテムを取得するにはどうすればよいですか?
解決
遅れて申し訳ありません、
だから最後に、私たちはそれをこのように動作させました:
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;
}
これにより、任意のサブテーブルにテンプレートが適用されます。
これが他の人に役立つことを願っています。