Reputation: 3036
Has anyone figured out how to use Crystal Reports with Linq to SQL?
Upvotes: 12
Views: 12579
Reputation: 17
The above code wont work in web application if you have dbnull values. You have to convert the results list object to dataset or datatable. There is no built in method for it. I have gone through the same issue and after hours of exploring on the internet, I found the solution and wanna share here to help anyone stuck up with it. You have to make a class in your project:-
public class CollectionHelper
{
public CollectionHelper()
{
}
// this is the method I have been using
public DataTable ConvertTo<T>(IList<T> list)
{
DataTable table = CreateTable<T>();
Type entityType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (T item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
return table;
}
public static DataTable CreateTable<T>()
{
Type entityType = typeof(T);
DataTable table = new DataTable(entityType.Name);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (PropertyDescriptor prop in properties)
{
// HERE IS WHERE THE ERROR IS THROWN FOR NULLABLE TYPES
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(
prop.PropertyType) ?? prop.PropertyType);
}
return table;
}
}
and here setting up your crystal report
CrystalReport1 cr1 = new CrystalReport1();
var results = (from obj in context.tSamples
where obj.ID == 112
select new { obj.Name, obj.Model, obj.Producer }).ToList();
CollectionHelper ch = new CollectionHelper();
DataTable dt = ch.ConvertTo(results);
cr1.SetDataSource(dt);
crystalReportsViewer1.ReportSource = cr1;
Upvotes: 0
Reputation: 17492
You can convert your LINQ result set to a List
, you need not strictly use a DataSet
as the reports SetDataSource
, you can supply a Crystal Reports data with an IEnumerable
. Since List
inherits from IEnumerable
you can set your reports' Data Source to a List, you just have to call the .ToList()
method on your LINQ result set. Basically:
CrystalReport1 cr1 = new CrystalReport1();
var results = (from obj in context.tSamples
where obj.ID == 112
select new { obj.Name, obj.Model, obj.Producer }).ToList();
cr1.SetDataSource(results);
crystalReportsViewer1.ReportSource = cr1;
Upvotes: 4
Reputation: 110111
The msdn doc's suggest that you can bind a Crystal Report to an ICollection.
Might I recommend a List(T) ?
Upvotes: 2
Reputation: 4305
Altough I haven't tried it myself it seems to be possible by using a combination of DataContext.LoadOptions to make it eager to accept relations and GetCommand(IQueryable) to return a SQLCommand object that preserves relations.
See more info on MSDN Forums.
Upvotes: 1