我正在使用Entity Framework作为工作项目的ORM,我需要能够将每个实体的值的一些写入现有的Excel模板。
需要将数据格式化为Excel表格,以便最终用户可以使用"=AVG(People_Table[Age])"
等公式来引用信息。 (注意,这只是一个简单的人为例子)。还需要将值导出为PDF。
我认为反思是以尽可能最不痛苦的方式输出信息的方式。但是,现在的问题是我想要将某些属性排除在写入电子表格之外。我也可能想按特定顺序编写属性并指定显示格式。
我可以这样做的一种方法是在属性上定义特定的数据属性。我喜欢这个忽略特定属性的答案:Exclude property from getType().GetProperties()。所以一个可能的解决方案可能是:
// class I want to export
public class PersonEntity {
[SkipAttribute] // per solution in the referenced answer
public int PersonId { get; set; }
[SkipAttribute]
public int ForeignKeyId { get; set; }
[Display(Order = 3)]
public int Age { get; set; }
[Display(Name="First Name", Order = 1)]
public string FirstName { get; set; }
[Display(Name="Last Name", Order = 2)]
public string LastName { get; set; }
/* additional properties remove for brevity */
}
问题我在上面的解决方案中看到,这个实体类现在正在做两件事:一,证明EF和数据库之间的映射,这是它的主要功能,以及两个提供有关如何使用类导出到Excel的信息。我认为这变得混乱而导致混乱,因为它(可能?)违反了SRP。而且,在导出到Excel时我只需要SkipAttribute
,大部分时间我都会忽略此属性。
我看到的替代解决方案可能是创建一组单独的类,这些类只包含所需的属性,并使用它来导出到Excel,然后使用AutoMapper等工具从EF Person映射到此类。 / p>
因此,导出类将是:
public class PersonExportModel {
[Display(Name="First Name")]
public string FirstName { get; set; }
[Display(Name="Last Name")]
public string LastName { get; set; }
public int Age { get; set; }
/* additional properties removed for brevity */
}
我只想使用反射将值转储到指定格式,使用ClosedXML或像ITextSharp这样的PDF渲染库。
关注以上的解决方案是,最终会有很多额外的代码,只是为了忽略一些不需要的属性(主要是PK' s,FK' s,和一些复杂的关系属性)。我也在这个问题上对EF类的任何更新,比如删除一个属性,将要求我也通过其他类并删除相应的属性。但是我喜欢这个解决方案,因为我对输出到Excel所需的数据不太困惑。
因此,我不得不在膨胀我的EF类以告诉它应该如何导出或创建与EF类紧密耦合的其他ExportModel之间,如果底层模型发生变化,将会很难更新。类之间的整个映射是一个真正的痛苦,可以通过AutoMapper缓解。然而,这伴随着混淆映射和性能损失的一系列问题。我可以忍受这些"问题"如果这意味着我不必在两个类之间手动映射。
我已经考虑过将工作分配到SSRS,但我需要能够将数据写入特定的现有工作簿,而我理解这是不可能的。我还需要能够创建命名表,我也理解这是不可能开箱即用的SSRS。我还需要创建两个报告,因为Excel输出看起来与PDF格式有很大不同。所以即使是SSRS也会带来很多额外的工作。
有关哪种解决方案可能最佳,或者可能采用其他方法的任何建议?这个项目的要求是不断变化的,所以我正在寻找一种尽可能轻松更新的解决方案。