How to use LINQ to SQL for binding data in CrystalReports 2008

By Mohammad Mahdi Ramezanpour at September 10, 2008 01:54
Filed Under: .NET General, ASP.NET, LINQ

Today I just decided to create some reports for one of our customers in Visual Studio 2008 and .NET Framework 3.5. Because I'm developing this application using LINQ, I wanted to use LINQ to SQL in CrystalReports. In this post I want to show you how you can use LINQ in order to bind data in CrystalReports.

Add CrystalReportViewer

At first, all sections are regular. You need to create a new application (I used Windows Application) and then add a Crystal Report Viewer to you specified form. When you add this control, you will see that Visual Studio added five new references to your application. These references are:

  • CrystalDecisions.CrystalReports.Engine
  • CrystalDecisions.Enterprise.Framework
  • CrystalDecisions.Enterprise.InfoStore
  • CrystalDecisions.ReportSource

You will need these libraries in order to let your application work with CrystalReports.

You made a place to show your reports in. Now you have to get started and create some reports. I want to add a new report by right clicking on my project, point to Add and then New Item. In the list of new items you need to point to Reporting section on the left side of "Add New Item" form and select Reporting. You items on templates side will be filtering to just 3 items:

  • Crystal Report
  • Report
  • Report Wizard

We want to work with CrystalReport here but for now I want to tell you other 2 items will work with Microsoft SQL Server Reporting Service that enables you to create flexible reports like CrystalReports but because CrystalReports is more common, most of developers prefer to use CrystalReports.

We just select Crystal Report and then select Add.

Because we want to work with LINQ classes, I need to create a LINQ to SQL class in order to add my tables to it and then use it in my CrystalReport file (For information about how you can create a LINQ to SQL class, Just check out my previous post: How to use SQL "IN" keyword in LINQ). Here is my tables structure:

LINQtoSQLClass

All I want is to show records from my Articles table. So I should implement this in my report. As you know when you're working with LINQ to SQL, tables become classes and fields become properties of those classes. When you want to add a new data source to your CrystalReport file (Data Fields section), there are some possibilities. You can use ADO.NET Datasets that enables you to use datasets you implemented in your application; and also you can use .NET Objects. It means that you can use classes in your application to be a data source for your report file. Because LINQ is based on classes, You must use .NET Objects in order to use LINQ to SQL as your Report's data source.

When you expand .NET Objects, you can see all classes in your application and also you can see the classes that made by LINQ class designer. Because I want to use my articles table I have to select Article class in the list as shown below:

Selecting Article Class

If you select this class as your data source you can see all fields available in the Articles table in database field section of our crystal report file. It means you can add each field you want to your report. So I just want to add Title field to my report (Details section):

Add Title To My Report

OK. That's all we need in our report file. Just one section left and that's let your report file know what data to show. You need to assign a database query to your file.

Let's go back to our report viewer file and go to code-behind section. In order to set your report file's properties, you have to create a new instance of your report file as following:

CrystalReport1 rpt = new CrystalReport1();

Now it's time to specify a query to your report file. A CrystalReport report file has a method named SetDataSource() that takes a datasource as the following types:

  • DataSet
  • DataTable
  • IDataReader
  • IEnumerable

LINQ to SQL, enables you to convert your data to a List<entityType>, Array and more. As you know List inherits IEnumerable, so All you need is to create a LINQ object and add a ToList() method to it and finally set the "SetDataSource()" method to our LINQ object as you can see in the code below:

ReportSampleDBDataContext db = 
    new ReportSampleDBDataContext();
var data = (from records in db.Articles 
            select records).ToList();
rpt.SetDataSource(data);


There is a property in our CrystalReportViewer control name ReportSource that enable you to specify which report file you want show in your CrystalReportViewer control. So you must set it up:

crystalReportViewer1.ReportSource = rpt;


It's working fine, isn't?

Comments

9/15/2008 10:07:53 PM #

nice job. anyway thanks mohammad mahdi.

Alireza Esmram

9/17/2008 3:07:32 AM #

You're welcome.

Admin

10/3/2008 9:34:32 PM #

sadi

I try to do the same but I got ""The report has no tables" error message ...

sadi

10/8/2008 9:49:19 PM #

Thanks for the know-how. There isn't much info on Crystal Reports using Linq to Sql.
It took me a while to figure out what your object, "CrystalReport1" was? Maybe I missed something but I discovered that it's really just of type CrystalDecisions.CrystalReports.Engine.ReportDocument (for anyone who's confused as I was.)

You could also just say:
CrystalReportSource1.ReportDocument.SetDataSource(data);

given that in your web file you have something like:

    <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server"
    AutoDataBind="True" Height="1055px" ReportSourceID="CrystalReportSource1"    
    Width="920px" />

<CR:CrystalReportSource ID="CrystalReportSource1" runat="server">
    <Report FileName="CrystalReport.rpt">
    </Report>
</CR:CrystalReportSource>

Also, you did not mention a "rpt" file as above.

Also, the linq query may need to include a "new" specifier after "select" to make sure the report does not come out blank.

Thanks again,
Would not have be able to learn a quick without your post.

Frank Neubecker

10/19/2008 8:55:56 PM #

admin

@Frank:
As I said in my post, This is a Windows Application not Web Application.
When you're working with CrystalReports in Windows Applications, .NET Framework will create a class for each of your CrystalReports files. You will use the class not file as I used in my post.

admin United States

10/20/2008 6:45:15 PM #

baixinha

Hi,

My english isn't good. I used your information:

CrystalReport1 relatorio = new CrystalReport1();
var data = (from p in baseDados.Cliente select p).ToList();
relatorio.SetDataSource(data);
crystalReportViewer1.ReportSource = relatorio;
(...)

When I run the aplication in the row relatorio.SetDataSource(data) i have a System.NotSupportedException.

You know what is my problem?

Thanks,
baixinha

baixinha Portugal

11/8/2008 10:33:58 AM #

admin

@baixinha:
It's a little confusing but I think the problem is from your Crystal Report.
Which version of Crystal Report you're using?
The above code sample had been tested on Crystal Reports 2008.

admin United States

11/17/2008 1:01:48 PM #

nesma

i have web Application and i user like u say by class it get me very strang error
this is the code

ClientsDataContext db=new ClientsDataContext();
        var Client = from p in db.ClientMains
                     select p.arName;            
              CrystalReportSource1.ReportDocument.SetDataSource(Client );
  pp.SetDataSource(Client);
and the error is
String cannot have zero length.
in line
pp.SetDataSource(Client);
can u help meFrown


nesma Egypt

11/17/2008 6:03:32 PM #

Admin

@nesma:
As I understood your comment correctly, The problem is that you have a null value in one of your fields you've used in your crystal report file.

Try to manage null values by check them with ISNULL() function in SQL Server, IIF function in VB, and ?? in C#.

If you still have this problem, just tell me.

Admin United States

11/18/2008 12:04:34 AM #

misxa

Thanks for the tips. It works for a single table. I tried creating a report out of LinQ query data, which joins two tables. When I debug the project, I can clearly see that query returns valid data, but nevertheless, report viewer shows only column headers on the report... Why is the report empty? I tried only with a sigle text column from each table, which makes things simple, but I got no results. I followed the procedure: created database context, generated valid LinQ data, created report, linked it's data source to the LinQ data result and finally, added that report to report viewer.

I lost several hours in vain.
Please, help...

misxa Serbia

11/18/2008 5:30:10 PM #

Admin

@misxa:
It's better to use stored procedure. As you may know, when you're adding a SP to your application using LINQ to SQL Classes, you can set output type (The default is Auto which returns an Auto generated type).

You can use that Auto type or you can create your own class for it.

When working with LINQ you can create partial classes. Try to use this and contact me if you still have this problem.

Admin United States

12/18/2008 8:31:32 PM #

Deepak

I am trying to do the same , i mean Crystal Reports with LINQ. The problem i am facing is , when i add .NET Objects from Database Expert, it is not showing me all the data fields(properties) of a Table(Class) on the Database Fields section. Specially it is not showing DateTime and boolean fields. Do you have any idea about the same, what could be the reason.

Thanks In Advance.

Deepak

Deepak United States

12/19/2008 8:36:52 PM #

Admin

@Deepak:
Thanks for the comment.
As I know, your problem is from your dbml file not Crystal Reports or something like this; because of your sentences. If you still have this problem, reinstalling Visual Studio may solve that issue.

Admin United States

12/28/2008 8:57:15 PM #

Iman Masihabadi

Thanks Mohammad,
Its Very Good

Iman Masihabadi Iran

12/29/2008 5:45:04 PM #

Admin

@Iman:
You're welcome.

Admin United States

1/6/2009 3:20:00 PM #

Peter

Dear Sir,

Thank you for the example. How do you access the .Net Objects if they are in a different class library and in an N-Layer solution. I have this problem with a web application where i have my WebUI and a Model class library with the LINQ classes. It only shows all the classes in the WebUI and not those in the Model class library. It seems that i can not browse to a specific assembly to find the LINQ classes. Can you help me please ?

Peter South Africa

1/6/2009 6:50:55 PM #

Admin

@Peter:
As I tried, you may need to do it programmatically. I really don't have any other idea about it. Smile
Anyone has?

Admin United States

1/17/2009 8:08:46 PM #

pingback

Pingback from hilpers-esp.com

Crystal report y datacontext | hilpers

hilpers-esp.com

1/28/2009 12:59:46 AM #

Nick

Do you know how to create a data source for a report that is not embedded using linq?  I have created a blank report and would like to insert a data source for the report and then add fields to the report from the inserted data source.  I have figured out how to add the fields to the report using the ReportClientDocument but I can't seem to figure out how to set a linq query as the data source for the report.  Any help you could offer would be greatly appreciated.

Nick United States

1/28/2009 8:30:36 PM #

Admin

@Nick:
As I can understand from your comment, you want to create such a dynamic report and you want to know how to set a LINQ data source to it.
As I described, You can make a use of SetDataSource method in your crystal report file.
Please describe more if I understood your question wrong.

Admin United States

2/3/2009 10:01:18 PM #

Nick

I've tried using that and keep receiving errors about having no tables.  Courtesy of a helpful coworker I have managed to get a SQL dataset that feeds the report using the SqlDataAdapter's TableMappings.Add().  Is there something similar to that for LINQ?

Nick United States

2/4/2009 1:25:01 PM #

Admin

@Nick:
Your words made me ask a question. What is the version of your Crystal Reports?
I will let you know that this mechanism is only works with Crystal Reports 2008 so that you cannot do such a thing on the earlier version of Crystal Reports.

Admin United States

2/4/2009 4:18:31 PM #

Nick

CR X R2.  I've managed to get the SQL dataset to work.  And The example you laid out above works fine.  I really was wanting to use LINQ to manage the dataset for this project, but I guess I'll use LINQ to gather information to build my statements and just use SQL to build the dataset for CR.

Thanks for the advice!

Nick United States

2/4/2009 6:40:04 PM #

Nick

Oops that's CR XI R2 not X.

Nick United States

3/18/2009 8:54:52 AM #

k

thanks for your sample,but if i have detail table like ArticlesJoinCategory Table in your sample and want to show its details in the subreport in my crystal report how can i link these 2 tables in crystal report,i did this by dataset but now i dont know how do with datacontext

k Iran

3/18/2009 10:42:19 AM #

Admin

@K:
If your tables have relations so you can access your child table from the parent.
assume that you have two tables:
1. Orders
2. OrderDetails
So the OrderDetails table is an object in your Orders table and you can access it.

Tell me if I didn't understand your comment correctly and describe a little more.

Admin United States

3/20/2009 8:11:47 PM #

Tim Chimento

Great Post! I'm having trouble using stored procedures though. If I do a straightforward SELECT in my SP the fields appear under the .NET Objects section in the Database Expert  and I can drag the fields on to the report. When I do something like SELECT COUNT (tablename.fieldname) though the field does not display in the Database Explorer. Here's an example of what I am talking about (this is from the stored procedure):

select a.Agency,

(Select count(t.ID) from [FlexFund_Transaction]t where a.id=t.agencyID) as Transactions,
(Select count(ti.ID)) as Items,
(Select sum(ti.Amount)) as 'Amount Spent'

In this case, the field 'Agency' appears in the Database Expert to drag on to my report but the fields 'Items' and 'Amount Spent' to not display. How can I get these two to display? When I execute the stored procedure in a stand alone query window I get all 3 fields to return.

Tim Chimento United States

3/20/2009 8:13:34 PM #

Tim Chimento

Sorry I mean the 'Database Expert' not 'Databse Explorer'

Tim Chimento United States

3/26/2009 6:46:57 PM #

Satrio

private void crystalReportViewer2_Load(object sender, EventArgs e)
        {
            CrystalReport1 rpt = new CrystalReport1();
            cbsplusDataClassesDataContext db = new cbsplusDataClassesDataContext();
            var report = (from r in db.Student_Details
                          select r).ToList();
            rpt.SetDataSource(report);
            crystalReportViewer2.ReportSource = rpt;

        }

i got NotSupportedException was unhandled in rpt.setdatasource(report);

can u help me? I use VS2008 pro..
thx b4...

Satrio

3/27/2009 8:20:44 AM #

Admin

@Tim:
When you adding a SP to your Database Model, you can set the output type.
So you can specified an object to it and the SP returns that type.
This is a LINQ to SQL feature.

@Satrio:
You need to set these items in the PreInit event.

Admin United States

3/27/2009 8:39:18 PM #

Tim Chimento

Is there an example somewhere of how to specify an object for the output type of a stored procedure? Thanks again.

Tim Chimento United States

3/28/2009 9:42:43 AM #

Admin

@Tim:
I'll blog a new post about it for you.

Admin United States

3/30/2009 9:49:02 AM #

Satrio

"NotSupportedException was unhandled"
DataSet does not support System.Nullable<>.

can you help me to fix it? i'm very new to linq n crystal reports..
thx b4

Satrio

3/30/2009 11:02:52 AM #

Admin

@Satrio:
Everything is OK in code. Trace your code again maybe the problem is from another part of your code.

Admin United States

3/30/2009 1:47:38 PM #

Admin

@Tim:
Update:
As I searched the internet about your question, found a lot of articles and stuff; so I decided not to blog this. You can google your question and you'll find it immediately.

Admin United States

3/30/2009 9:55:21 PM #

Ashwani

try to do the same but I got ""The report has no tables" error message ...


var data = (from records in objdb.tblFacilities
                        select records).ToList();
            orpt.SetDataSource(data);
            CrystalReportViewer1.ReportSource = orpt;

Ashwani India

6/3/2009 8:01:45 PM #

Manzi

Thanks indeed! This is a great job!

Manzi South Africa

6/15/2009 1:38:27 PM #

Brij

This is nice article.

Question: I want to develop the report with LINQ class in N-Tier technology. I have tried to create report with .NET objects but it is displayed only from the same project class libraries. In our case, data layer is in different project so can you please explain us how to get the class libraries from other project.

Thanks in advance.

Brij India

7/2/2009 8:12:38 AM #

rajah

how creating dynami report???? in wpf ???and linq???[

rajah Iran

7/13/2009 12:33:58 PM #

Riyaz

Hi
The example you showed is of LinqtoSql classes (dbml) file, but in my project i have not created dbml file, instead created normal module to create linq classes, how can i select these classes for crystal reports data source?

Please reply

Riyaz U.A.E.

7/14/2009 11:58:45 PM #

Jules Jurgensen

Do you accept guest posts? I would love to write couple articles here.

Jules Jurgensen United States

8/6/2009 6:24:01 PM #

Dloadmp3

what is this! are you kiddin me!

Dloadmp3 United States

8/8/2009 4:48:01 AM #

San Diego Real Estate Investing

I am thankful for such a great post with many new things to learn� Thanks, you cleared up some things for me.

San Diego Real Estate Investing United States

8/8/2009 4:48:07 AM #

Learn Master Guitar

Funny, I actually had this on my mind a few days ago and now I come across your blog...

Learn Master Guitar United States

8/19/2009 8:14:15 PM #

MinhTho

Thanks for everybody, it's very useful for me

MinhTho Vietnam

9/15/2009 8:05:04 AM #

Anahita

hi,i've done what u said,but when i run it my report is empty and i just have the columns name,i mean just the view
what should i do?

Anahita Iran

9/15/2009 8:13:13 AM #

Admin

@Anahita:
I think your problem is because of your datasource. If you set your datasource correctly, it has to work.
Checkout your report's datasource Smile

Admin United States

9/15/2009 8:34:53 AM #

Anahita

i use that datasource for my grid view and that works there,

Anahita Iran

9/15/2009 9:09:59 AM #

Anahita

no,i've use that database for my datagrid view,and that works true

Anahita Iran

9/15/2009 9:11:51 AM #

Anahita

is it possible to send a column in code,to crystal report?
i mean a linq query,that contains a column?
sorry for asking to much

Anahita Iran

9/15/2009 9:38:43 AM #

Admin

@Anahita:
In fact, I cannot realize what you've done. Please send me your code or contact me for more information.

Admin United States

9/16/2009 12:50:59 AM #

Anahita

hi,i undersand which part was wrong that it doesnt show my data,i used data from to table,and crystal report doesnt support it
how should add data from 2 table?

Anahita Iran

9/16/2009 3:17:50 AM #

Admin

@Anahita:
In my opinion, The best way to do such a thing is to use a View.
Otherwise, you can use anonymous types to do so.

Admin United States

5/20/2010 11:19:56 AM #

pingback

Pingback from 110.rkwrh.com

Laguna Pf5000 Foam, F500 Mold

110.rkwrh.com

Comments are closed

Currently Reading

Quote of the day

Send Persian SMS