MVC Crystal Reports

0

They could help me with the following:

I have two related models, one Customers and another Orders, I try to generate a report with crystal reports of the orders generated, they would be something like when a customer buys something in a store, a purchase order is generated but this order contains inside of your model the data of the client that generated the order, ok, I intend that when generating the report of this order, the customer's data will appear as identification, email, address, etc., the problem is that I am sooooooooo new in the MVC theme and even more in crystal report, and the report only shows me the id of the client How to do to nest the data of the client in the report? I leave some additional data.

my models:

public class Order
{
    [Key]
    public int OrderId { get; set; }

    [Display(Name = "Consecutivo")]
    public string Consecutive{ get; set; }

    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }

    [Required(ErrorMessage = "Este campo obligatorio")]
    [Display(Name = "Fecha")]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime EntryDate { get; set; }

    public int PaymentTypeId { get; set; }
    public virtual PaymentType PaymentType { get; set; }
}


public class Customer
{
    [Key]
    public int CustomerId { get; set; }

    public int TypeDocumentId { get; set; }
    public virtual TypeDocument TypeDocuments { get; set; }

    [Required(ErrorMessage = "Este campo es obligatorio")]
    [MaxLength(50, ErrorMessage = "Max 50 caracteres")]
    [RegularExpression("^[0-9]*$", ErrorMessage = "Sólo caracteres numéricos")]
    [DataType(DataType.Text)]
    [Display(Name = "Nº Documento")]
    [Index("Index_Document_Customer", IsUnique =true)]
    public string Document { get; set; }

    [Required(ErrorMessage = "Este campo es obligatorio")]
    [MaxLength(250, ErrorMessage = "Max 250 caracteres")]
    [DataType(DataType.Text)]
    [Display(Name = "Nombre")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Este campo es obligatorio")]
    [MaxLength(50, ErrorMessage = "Max 50 caracteres")]
    [DataType(DataType.Text)]
    [Display(Name = "Apellido")]
    public string LastName { get; set; }

    [MaxLength(250, ErrorMessage = "Max 250 caracteres")]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "e-mail")]
    public string Email { get; set; }

    [MaxLength(250, ErrorMessage = "Max 250 caracteres")]
    [DataType(DataType.Text)]
    [Display(Name = "Dirección")]
    public string Address { get; set; }

    [MaxLength(25, ErrorMessage = "Max 25 caracteres")]
    [RegularExpression("^[0-9]*$", ErrorMessage = "Sólo caracteres numéricos")]
    [DataType(DataType.PhoneNumber)]
    [Display(Name = "Teléfono")]
    public string Phone { get; set; }

    [Display(Name ="Nombre")]
    public virtual string FullName { get{ return string.Format("{0} {1}", FirstName, LastName); } }

    public virtual ICollection<Order> Orders { get; set; }
    public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}

here the controller code:

                    db.SaveChanges();
                    transaction.Commit();
                    ReportDocument rd = new ReportDocument();
                    rd.Load(Path.Combine(Server.MapPath("~/Reports"), "Orders.rpt"));
                    rd.SetDataSource(db.Orders.Where(o=>o.OrderId == orderAux.OrderId).ToList());
                    Response.Buffer = false;
                    Response.ClearContent();
                    Response.ClearHeaders();
                    Stream stream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
                    stream.Seek(0, SeekOrigin.Begin);
                    return File(stream,"aplicattion/pdf",string.Format("{0}.pdf",orderAux.OrderId));'

here the result of the report

    
asked by Steven Hernández 17.08.2018 в 13:33
source

3 answers

0

Your problem is simple Steven, it's called "Lazy Loading" in the Entity Framework. In your query to bd you are only loading the id of the client, to load the data referring to Customer, you must make an Include in your query. example:

rd.SetDataSource(db.Orders.Include(o => o.Customer).Where(o=>o.OrderId == orderAux.OrderId).ToList());
    
answered by 17.08.2018 в 16:56
0

Vicente thank you very much for answering, more or less I am clear what you explain to me in your comment, but what I do not understand is how I add it in the crystal report designer I passed you a photo.

This is the part I do not understand, in the designer how to add it if "Customer" does not appear, this is the "CustomerId"

    
answered by 17.08.2018 в 18:24
0

I think your problem is not so simple. I have not managed to run linq with crystal reports directly, I have always had to use a dataset to pass the linq data to the crystal reports. I explain. When you have more than a table in the report, you must add all the tables to the report. You now have only the AgoraF_Models_Order table, and you have to add the Customer table,

On that screen, where to stop fields from the database, click on the right mouse button and "database assistant". In the window that appears you must add your class "customer" and in links tell you the fields of the tables that are related.

When you finish you should see something similar to:

If you notice, the fields of the tables appear

The problem is that for crystal reports each table belongs to a different database (or connection), so then, even if you do what Vicente Almea says,

rd.SetDataSource(db.Orders.Include(o => o.Customer).Where(o=>o.OrderId == orderAux.OrderId).ToList());

It does not load the data, or at least it does not load them to me.

Solutions:

  • Or you create a view with the related tables that have the data you want to show.

  • Add a DataSet to your project and add all the tables you want to show. and then:

  • i. You make your query linq:    List orders = db.Orders.Include (or = > o.Customer) .Where (o = > o.OrderId == orderAux.OrderId) .ToList ());

    ii. You load the customer and orders tables of the dataset with the data from the previous step.

    iii. cr.setDataBase (tudataset)

    I hope it works for you, although if someone has managed to run the crystal reports with linq and more than one table, I'm delighted to see the solution, but I think it does not work.

        
    answered by 18.08.2018 в 11:18