Question

Has anyone figured out how to use Crystal Reports with Linq to SQL?

Was it helpful?

Solution

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;

OTHER TIPS

The msdn doc's suggest that you can bind a Crystal Report to an ICollection.

Might I recommend a List(T) ?

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.

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top