我需要生成几个报告,其中许多报告只是我数据库中的实体表。实体可以是任何类型,我不会总是需要整个实体。
我目前的方法是创建一个ViewModel,其中包含List<List<string>>
类型的字段,该字段代表我的表,其中每一行都是一个单元格列表。然后,视图只需要枚举每行和每列来创建表。
public class ListReportViewModel
{
public string Title;
public List<string> Headings;
public List<List<string>> Rows;
}
然后我有控制器代码来填充标题和行:
// Get the entities for the report
var tickets = ( from t in _db.Ticket.Include("Company").Include("Caller")
select t );
// Populate the column headings
data.Headings = new List<string>();
data.Headings.Add( "Ticket ID" );
data.Headings.Add( "Company" );
data.Headings.Add( "Caller" );
data.Headings.Add( "Reason for Call" );
// Temporary staging variables
List<List<string>> rows = new List<List<string>>();
List<string> row;
// Populate temporary variables
foreach ( var ticket in tickets )
{
row = new List<string>();
row.Add( ticket.TicketID.ToString() );
row.Add( ticket.Company.Name );
row.Add( ticket.Caller.FirstName + " " + ticket.Caller.LastName );
row.Add( ticket.Subject );
rows.Add( row );
}
// Populate ViewModel field
data.Rows = rows;
虽然这有效但似乎效率低下。我循环遍历整个结果集只是为了填充ViewModel,然后视图将不得不再次遍历它以构建报告。
我的问题:有更简单的方法吗?如果我可以让我的Linq查询返回IEnumerable<IEnumerable<string>>
,那么我可以使用“data.Rows = tickets
”这一行,视图就可以循环显示。
我认为必须有更好的方法来做到这一点,我不知道。
答案 0 :(得分:1)
答案 1 :(得分:0)
这是我在查看Mathias的建议后想出的解决方案。这不是世界上最快的东西,但现在已经足够快了。
我将我的ViewModel更改为使用IEnumerable
而不使用标题类型和字典:
public class ListReportViewModel
{
public string Title;
public Dictionary<string,string> Headings;
public IEnumerable Data;
}
在我的控制器中,我以正常方式选择实体,并填充标题字典以定义我要报告的内容:
var data = new ListReportViewModel();
data.Title = "Closed Calls";
data.Headings = new Dictionary<string, string>();
data.Headings.Add( "TicketID", "ID" );
data.Headings.Add( "Company.Name", "Company" );
data.Headings.Add( "Caller.FirstName", "Caller" );
data.Headings.Add( "Subject", "Reason for Call" );
data.Headings.Add( "ClosedTime", "Closed" );
data.Headings.Add( "ClosedBy.LoginName", "Closed By" );
data.Data = ( from t in _db.Ticket.Include( "Company" ).Include( "Caller" ).Include( "ClosedBy" )
where !t.Open
orderby t.ClosedTime ascending
select t );
return View( "list", data );
然后,处理的内容由视图完成,以便通过ViewModel流失并填充表格:
bool isFirstRow = true;
Type rowType = typeof( System.Data.Objects.DataClasses.EntityObject );
Type propType;
System.Reflection.PropertyInfo propInfo;
object propObject;
string[] propNames;
foreach ( var row in Model.Data )
{
if ( isFirstRow )
{
// Get the type of entity we're enumerating through
rowType = row.GetType();
isFirstRow = false;
}
// Enumerate through the columns
foreach ( var kvp in Model.Headings )
{
propNames = kvp.Key.Split( '.' );
propObject = row;
propType = rowType;
// Drill down through the entity properties so we can
// handle properties like "Ticket.Company.Name"
foreach ( var propName in propNames )
{
try
{
propInfo = propType.GetProperty( propName );
propObject = propInfo.GetValue( propObject, null );
propType = propObject.GetType();
}
catch ( NullReferenceException ) { }
}
try
{
Response.Write( "<td>" + Html.Encode( propObject.ToString() ) + "</td>" );
}
catch ( NullReferenceException )
{
Response.Write( "<td>--</td>" );
}
}
}