【问题标题】:Creating Reports in ASP.Net with Entity Framework使用实体框架在 ASP.Net 中创建报表
【发布时间】:2013-02-15 06:52:55
【问题描述】:

我们希望将 Microsoft Reports - SSRS 添加到我们的一个内部网站。

数据库已安装所有报告功能。

该网站对所有数据都使用 Entity Framework 4。

我已经能够使用创建数据集 (*.XSD) 的老式方法创建报告,并且效果很好。

不过,我的问题是,是否可以利用站点中现有的实体框架来获取报告所需的数据?而不必重新发明轮子并制作整个数据集以及关系等。

这是一个网站而不是应用程序,所以这个 (http://weblogs.asp.net/rajbk/archive/2010/05/09/creating-an-asp-net-report-using-visual-studio-2010-part-1.aspx) 似乎不适用;我没有看到 DataSource(在教程的第 2 部分中)

更新

作为旁注,我们希望避开昂贵的第三方控件等。

另外,查看问题的另一种方法可能是从实体框架实体模型生成 *.XSD;这可能吗?虽然会让我们启动并运行它并不理想..

【问题讨论】:

    标签: asp.net entity-framework reporting-services


    【解决方案1】:

    您可以将 LINQRDLC Report 一起使用,非常容易使用

    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();
    

    【讨论】:

      【解决方案2】:

      我们也将 SSRS 用作“本地”报告。我们在 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(); 
      

      【讨论】:

        【解决方案3】:

        下面是我如何在我的一个 .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;
                }
        

        【讨论】:

          【解决方案4】:

          我的方法一直是使用带有对象数据源的 RDLC 文件并在“本地”模式下运行它们。这些数据源是……我的实体!通过这种方式,我使用了所有与我的 Web 应用程序相同的业务逻辑、字符串格式、文化意识等。有一些怪癖,但我能够忍受它们:

          • RDLC 文件不喜欢存在于 Web 项目中。我们创建一个单独的虚拟 winform 项目并在其中添加 RDLC 文件。
          • 我不在查看器中显示报告。我让用户下载 PDF、Word 或 Excel 文件并选择在本机查看器中保存或打开。这可以省去很多麻烦,但可能会让一些人望而却步,具体取决于要求。对于移动设备来说,这很不错。
          • 由于您没有使用 SSRS,因此您无法获得不错的订阅功能。如果需要,您将构建它。不过,在很多方面,我更喜欢这个。

          不过,好处真的很不错:

          • 我正在使用我已经为我的观点编写的所有相同的业务逻辑。
          • 我有一个自定义的 ReportActionResult 和 DownloadReport 控制器方法,它允许我通过单个 URL 运行任何报告。这非常方便。它确实使自定义订阅组件更容易。
          • 报表开发似乎进展得很快,现在我只需要调整实体部分类即可在这里或那里进行一些调整。另外 - 如果我需要稍微改变数据的形状,我有 LINQ。

          【讨论】:

          • 如何为 VS 2013 设置对象数据源
          • 这个答案是一个很长的评论,但是答案。
          【解决方案5】:

          诀窍是创建一个带有空白数据源连接字符串、空白查询块和空白 DataSetInfo 的报告 (.rdlc)(我必须手动修改 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>
          

          现在在一个页面事件中,我在一个 DropDownList 上使用了 SelectedIndexChanged,如下绑定报表数据源:

          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】:

          您可以将 WCF 服务用作数据源,从而将应用程序数据和逻辑重新用于报表。至少我相信这需要一个 SQL-server 标准版。所以免费的 SQL-express 版本是不行的。

          【讨论】:

          • 也尝试过这种方法,尽管这似乎只适用于 Web 应用程序而不是网站,因为报表设计器(选择数据源的向导)中没有引用- 引用不存在。
          • 这是在报告中访问代码的唯一方法。如果您无法为 WCF 服务设置 Web 应用程序,您最好使用普通 sql 或存储过程访问您的数据
          • 是的,开始看到了。在提出这个问题的同时,我们为报告构建了存储过程;只是真的不喜欢在不同的地方有数据访问逻辑......
          猜你喜欢
          • 2011-11-22
          • 2013-06-18
          • 1970-01-01
          • 2017-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-10
          相关资源
          最近更新 更多