Создание отчетов в ASP.Net с платформой Entity Framework
Мы хотим добавить Microsoft Reports - SSRS на один из наших внутренних веб-сайтов.
В базе данных установлены все функции отчетности.
Веб-сайт использует Entity Framework 4 для всех данных.
Мне удалось создать отчет, используя старомодный способ создания DataSet (*.XSD), и это хорошо работает.
Однако мой вопрос: можно ли использовать существующую Entity Framework на сайте для данных, требуемых отчетами? Вместо того, чтобы повторно изобретать колесо и создавать целый DataSet, а также отношения и т.д.
Это веб-сайт, а не приложение, поэтому это (http://weblogs.asp.net/rajbk/archive/2010/05/09/creating-an-asp-net-report-using-visual-studio-2010-part-1.aspx), похоже, не применяется; Я не вижу DataSource (часть 2 учебника)
Обновление
В качестве примечания мы хотели бы избегать дорогостоящих сторонних элементов управления и т.д.
Кроме того, другой способ взглянуть на проблему может заключаться в том, чтобы генерировать *.XSD из модели сущности framework entity; Это возможно? Это не идеальное, хотя бы заставило нас работать.
Ответы
Ответ 1
Ниже приведен краткий пример того, как я установил источник данных отчета в одном из моих приложений .NET winForms.
public void getMyReportData()
{
using (myEntityDataModel v = new myEntityDataModel())
{
var reportQuery = (from r in v.myTable
select new
{
l.ID,
l.LeaveApplicationDate,
l.EmployeeNumber,
l.EmployeeName,
l.StartDate,
l.EndDate,
l.Supervisor,
l.Department,
l.Col1,
l.Col2,
.......,
.......,
l.Address
}).ToList();
reportViewer1.LocalReport.DataSources.Clear();
ReportDataSource datasource = new ReportDataSource("nameOfReportDataset", reportQuery);
reportViewer1.LocalReport.DataSources.Add(datasource);
Stream rpt = loadEmbededReportDefinition("Report1.rdlc");
reportViewer1.LocalReport.LoadReportDefinition(rpt);
reportViewer1.RefreshReport();
//Another way of setting the reportViewer report source
string exeFolder = Path.GetDirectoryName(Application.ExecutablePath);
string reportPath = Path.Combine(exeFolder, @"rdlcReports\Report1.rdlc");
reportViewer1.LocalReport.ReportPath = reportPath;
reportParameter p = new ReportParameter("DeptID", deptID.ToString());
reportViewer1.LocalReport.SetParameters(new[] { p });
}
}
public static Stream loadEmbededReportDefinition(string reportName)
{
Assembly _assembly = Assembly.GetExecutingAssembly();
Stream _reportStream = _assembly.GetManifestResourceStream("ProjectNamespace.rdlcReportsFolder." + reportName);
return _reportStream;
}
Ответ 2
Мой подход всегда заключался в использовании файлов RDLC с объектными источниками данных и их запусках в локальном режиме. Эти источники данных... мои сущности! Таким образом, я использую все те же бизнес-логику, форматирование строк, понимание культуры и т.д., Которые я использую для своих веб-приложений. Есть некоторые причуды, но я смог с ними жить:
- Файлы RDLC не любят жить в веб-проектах. Мы создаем отдельный проект фиктивной winform и добавляем туда файлы RDLC.
- Я не показываю отчеты в телезрителе. Я разрешаю пользователю загружать файл PDF, Word или Excel и выбирать сохранение или открытие в собственном средстве просмотра. Это экономит кучу головных болей, но может отбросить некоторых людей в зависимости от требований. Для мобильных устройств это довольно хорошо.
- Поскольку вы не используете SSRS, вы не получаете хорошую функцию подписки. Вы собираетесь построить это, если потребуется. Тем не менее, я предпочитаю это.
Однако преимущества действительно приятные:
- Я использую все те же знания бизнес-логики, которые я уже написал для своих просмотров.
- У меня есть настраиваемый метод контроллера ReportActionResult и DownloadReport, который позволяет мне по существу запускать любой отчет по одному URL-адресу. Это может быть ОЧЕНЬ удобно. Он уверен, что упрощает создание настраиваемого компонента подписки.
- Отладка отчетов кажется довольно быстрой, теперь мне нужно только настроить частичные классы объектов, чтобы немного подправить что-то здесь или там. Кроме того - если мне нужно немного изменить данные, у меня есть LINQ.
Ответ 3
Мы также используем SSRS как "локальные" отчеты. Мы создаем Views на SQL-сервере, затем создаем этот объект в нашем приложении вместе с другими модулями домена EF и запрашиваем этот объект с помощью нашего DbContext. Мы используем страницу ASPX и используем код позади (Page_Load), чтобы получить данные, переданные в отчет.
Вот пример того, как мы запрашиваем его в событии Page_Load:
var person = MyDbContext
.Query<ReportModel>()
.Where(x => x.PersonId == personId)
.Where(x => x.Year == year)
.Select(x =>
{
PersonId = x.PersonId,
Year = x.Year,
Name = x.Name
});
var datasource = new ReportDataSource("DataSet1", person.ToList());
if (!Page.IsPostBack)
{
myReport.Visible = true;
myReport.ProcessingMode = ProcessingMode.Local;
myReport.LocalReport.ReportPath = @"Areas\Person\Reports\PersonReport.rdlc";
}
myReport.LocalReport.DataSources.Clear();
myReport.LocalReport.DataSources.Add(datasource);
myReport.LocalReport.Refresh();
Ответ 4
Вы можете использовать WCF-службу как источник данных и, таким образом, повторно использовать данные приложения и логику для своего отчета. Для этого требуется стандартная версия SQL-сервера, по крайней мере, я считаю. Таким образом, нет бесплатной версии SQL-express.
Ответ 5
Хитрость заключается в создании отчета (.rdlc) с пустой строкой соединения источника данных, пустым блоком запроса и пустой DataSetInfo (мне пришлось вручную изменить xml). Они должны существовать в файле и быть пустыми следующим образом:
SomeReport.rdlc (viewing as xml)
...
<DataSources>
<DataSource Name="conx">
<ConnectionProperties>
<DataProvider />
<ConnectString />
</ConnectionProperties>
<rd:DataSourceID>19f59849-cdff-4f18-8611-3c2d78c44269</rd:DataSourceID>
</DataSource>
</DataSources>
...
<Query>
<DataSourceName>conx</DataSourceName>
<CommandText />
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
</Query>
<rd:DataSetInfo>
<rd:DataSetName>SomeDataSetName</rd:DataSetName>
</rd:DataSetInfo>
теперь в событии страницы я использую SelectedIndexChanged в DropDownList, привязываю источник данных отчета следующим образом:
protected void theDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
if (theDropDownList.SelectedIndex == 0)
return;
var ds = DataTranslator.GetRosterReport(Int64.Parse(theDropDownList.SelectedValue));
_rvReport.LocalReport.ReportPath = "SomePathToThe\\Report.rdlc";
_rvReport.LocalReport.DataSources.Add(new ReportDataSource("SomeDataSetName", ds));
_rvReport.Visible = true;
_rvReport.LocalReport.Refresh();
}
Ответ 6
Вы можете использовать LINQ с отчет RDLC, который довольно прост в использовании
LinqNewDataContext db = new LinqNewDataContext();
var query = from c in db.tbl_Temperatures
where c.Device_Id == "Tlog1"
select c;
var datasource = new ReportDataSource("DataSet1", query.ToList());
ReportViewer1.Visible = true;
ReportViewer1.ProcessingMode = ProcessingMode.Local;
ReportViewer1.LocalReport.ReportPath = @"Report6.rdlc";
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(datasource);
ReportViewer1.LocalReport.Refresh();