The CSLA.NET books have some guidance for reports, but I have found that a little different solution has worked better for us. Reports usually have some similar characteristics.
- The are read only. Static data.
- Logic for reports are usually in stored procs.
- Usually different than the standard business object formats.
So I got a little push back and I didn't quite like the idea of creating a seperate business object for each report. We weren't using any validation or code generation. However, I didn't want to lose some of the power of CSLA.NET like the DataPortal. I didn't want to use just classic data access and use datasets directly from the database.
We came up with a hybrid report business object. Instead of calling the data access directly, we used the dataportal_fetch and put the logic in there like a normal business object. However this object only has one property, ReportDataSet. This still allows us to use remoting or WCF if we want a middle tier. Each report then is a new Factory method passing in a custom criteria object including the stored proc name and a parameters collection.
The returned object's dataset property then can be bound to the report. The only thing we lose is property names.
Below is basic example of a ReportFactory class.
-Mike
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Specialized;
namespace BusinessObjects
{
public class ReportFactory : Csla.BusinessBase<ReportFactory>
{
private DataSet reportDataSource;
public DataSet ReportDataSource
{
get { return reportDataSource; }
}
public static ReportFactory GetMonthEndTotalsReport(int Month, int Year)
{
ReportCriteria criteria = new ReportCriteria();
criteria.SPName = "usp_MonthEndTotalsReport";
criteria.SQLParameters.Add("@Month", Month);
criteria.SQLParameters.Add("@Year", Year);
return Csla.DataPortal.Fetch<ReportFactory>(criteria);
}
[Serializable()]
protected class ReportCriteria
{
public string SPName = "";
public ListDictionary SQLParameters = new ListDictionary();
}
protected void DataPortal_Fetch(ReportCriteria criteria)
{
using (SqlConnection conn = new SqlConnection(Database.Connection))
{
conn.Open();
using (SqlCommand cm = conn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = criteria.SPName;
foreach (string param in criteria.SQLParameters.Keys)
{
cm.Parameters.AddWithValue(param, criteria.SQLParameters[param]);
}
reportDataSource = new DataSet();
using (SqlDataAdapter da = new SqlDataAdapter(cm))
{
da.Fill(reportDataSource);
}
}
}
}
protected override object GetIdValue()
{
return Guid.NewGuid();
}
}
}