目标:通用导出为CSV与表
我们的应用程序是使用多种类型的建(例如人,PersonSite(ICollection的),站点 - 我选择了这些类,因为他们有关系)。我们想要做的是能够从Excel表格中的第一个类型(Person)中导出一些属性,然后从同一个Excel文件中的第二个类型(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| |________________________| |________________|
所以对于包含在列表中的每个PersonSite,我们想创建一个将只是人的表格后插入一个表格。
因此,这是怎么看待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 EXPORTER |________| CSV TABLE (T)|__________| CSV COLUMN (T)| |______________| |______________| |_______________| | |1..* ______|________ | CSV ROWS (T) | |_______________|
所以CSVTable使用一个通用的类型,它是IObject提取(如在不同的类中使用)。
表可以有多个表(例如Person表具有PersonSite表,PersonSite表具有Site表)。但是使用的类型是不同的,因为我们浏览不同的类(这些类必须有关系)。
当添加一个子表,以一个表中,我们应当提供连接表达式将抓住正确类型的从主项中的项(人=> 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;
}
}
有没有人做过类似的东西?还是我们走错了路? 如果这似乎是一条好路径,我们如何创建链接(关系)表达式并使用它来检索最后一次调用中使用的正确项目?
伟大你有它的工作,你可以关闭它吗? – 2012-02-19 21:22:56
我同意@MicahArmantrout;对于搜索类似问题的其他人,您是否可以将更新发布为答案并接受它?它也将防止将回答者试图解决您的问题..谢谢:-) – Jonno 2012-03-13 14:07:10
@Whoami请张贴您的解决方案作为答案。你可以接受这个答案(有时你需要等待一两天才能完成)。如果你这样做,你会问问题和答案,因为你已经做了一些出色的工作。现在完成步骤(: – 2012-03-22 20:24:20