Nous cherchons à ajouter Microsoft Reports - SSRS à l'un de nos sites Web internes.
La base de données contient toutes les fonctionnalités de rapport installées.
Le site Web utilise Entity Framework 4 pour toutes les données.
J'ai pu créer un rapport en utilisant la méthode traditionnelle de création d'un DataSet (* .XSD) et cela fonctionne bien.
Ma question cependant, est-il possible d'utiliser le Entity Framework existant sur le site pour les données requises par les rapports? Plutôt que de devoir réinventer la roue et créer un DataSet complet, avec des relations, etc.
C'est un site Web et non une application, donc ( http://weblogs.asp.net/rajbk/archive/2010/05/09/creating-an-asp-net-report-using-visual-studio-2010- partie-1.aspx ) ne semble pas s'appliquer; Je ne vois pas le DataSource (dans la partie 2 du tutoriel)
Mettre à jour
En passant, nous souhaitons éviter les contrôles coûteux, effectués par des tiers, etc.
De plus, une autre façon d’envisager le problème pourrait être de générer le fichier * .XSD à partir du modèle d’entité cadre-entité; Est-ce possible? Ce n’est pas idéal, mais cela nous permettrait d’être opérationnels.
Vous trouverez ci-dessous un exemple rapide de la définition de la source de données de rapport dans l’une de mes applications .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;
}
Mon approche a toujours été d'utiliser des fichiers RDLC avec des sources de données objet et de les exécuter en mode "local". Ces sources de données sont ... mes entités! Ainsi, j'utilise la même logique métier, le même formatage des chaînes, la même sensibilité à la culture, etc. que pour mes applications Web. Il y a quelques bizarreries, mais j'ai pu vivre avec elles:
Cependant, les avantages sont vraiment gentils:
Nous utilisons nous aussi SSRS comme des rapports "locaux". Nous créons des vues sur le serveur SQL, puis créons cet objet dans notre application avec les autres modèles de domaine EF et interrogons cet objet à l'aide de notre DbContext. Nous utilisons une page ASPX et utilisons le code situé derrière (Page_Load) pour que les données soient transmises au rapport.
Voici un exemple de la façon dont nous l'interrogons dans l'événement 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();
L'astuce consiste à créer un rapport (.rdlc) avec une chaîne de connexion à une source de données vide, un bloc de requête vide et un DataSetInfo vierge (je devais modifier le xml manuellement). Ils doivent exister dans le fichier et être vides comme suit:
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>
maintenant, dans un événement de page, j'utilise un SelectedIndexChanged sur un DropDownList, lie la source de données du rapport comme suit:
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();
}
Vous pouvez utiliser un service WCF comme source de données et ainsi réutiliser vos données d'application et votre logique pour votre rapport. Cela nécessite au moins une édition standard du serveur SQL. Donc, rien ne peut être fait avec l'édition gratuite de SQL-Express.
Vous pouvez utiliserLINQavec Rapport RDLC qui est assez facile à utiliser
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();