2

I'm bulding a WPF application on visual studio 2013 with Entity-Framework (Code First).

I have a Order class, that has a virtual property for Customer.

public class Order
{
  public int OrderId { get; set; }
  public DateTime OrderDate { get; set;}
  public virtual Customer Customer { get; set; }
}

public class Customer
{
  public int CustomerId { get; set; }
  public string Name  { get; set; }
  public string DocumentNumber { get; set; }
  public DateTime BirthDate { get; set; }
}

I'm trying to show the customer's name on report formula. I've tried:

=First(Fields!Customer.Value.Name, "MyDataSet")
=First(Fields!Customer.Name.Value, "MyDataSet")

and

=Fields!Customer.Value.Name
=Fields!Customer.Name.Value

It just shows #Error on that field. Other fields from Order are displayed properly.

It works:

=First(Fields!OrderDate.Value, "MyDataSet")

I loaded the Customer by using Include when I retrieve the entity from context. So a null reference is not the problem.

Order order = context.Orders.Include(o => o.Customer).Where(o => o.OrderID == id).FirstOrDefault();

I searched the following and others, but sounds like is just for visual studio 2010 or just didn't work:
Bind child object property with in rdlc (Report)
http://wraithnath.blogspot.com.br/2011/04/reportviewer-object-datasource-nested.html

Is there some thing I didn't do or I should work another way on that, like some kind of "code-first-view"?

Community
  • 1
  • 1
Murilo
  • 1,112
  • 1
  • 18
  • 33
  • 2
    I believe overriding the `toString()` method might be worth a shot. But ultimately I believe you're better off using 2 data sets or creating a new data table where you join the tables, using a view or linq operation. – Oceans Nov 10 '15 at 15:31
  • Looks like overriding ToString() didn't work. thanks – Murilo Nov 10 '15 at 15:42
  • It was worth a shot. Could you add the code from the class `Customer` to your post? I'll try and reconstruct your environment to test, also what .net framework are you using? – Oceans Nov 10 '15 at 15:54
  • Ok I will edit the post. I use .net framework 4.5, visual studio 2013 and EF 6. I'm about to give up. I will create a class that will represent a view like, order id, order date, customer name, than I will use some linq operation as you said. – Murilo Nov 10 '15 at 16:06

2 Answers2

1

I'm not sure if this is the accepted standard for doing this kind of thing but what I've found to be the most reliable. (VS Rdlc work is bugged to hell and not well documented in the wpf realm)

So you have your dataset for your 'Order' object which contains the customer object you're trying to access properties from. Now, create another dataset of the 'Customer' object.

Then in code, populate your 'Order' object with everything as you normally would and then set the second dataset's binding source we created based on your 'Customer' object to the 'Customer' object that is inside your 'Order' object

Order order = new Order();
order.OrderId = 1;
order.OrderDate = DateTime.Now;
order.Customer = new Customer("John", "Shmoe");

OrderBindingDataSet.DataSource = order;
CustomerBindingDataSet.DataSource = order.Customer;

Hope this helps, I know from personal experience how irritating it is to have to use this piece of work along with it having little to no documentation for these kind of things. :)

Tyler Benzing
  • 1,116
  • 11
  • 25
  • Thanks. I've done that, but I'd like to work with only one dataset, like my formula that doesn't work, but it looks like there's no way to do that on the way I want. I think I will look for some free reporting tool for visual studio 2013 instead of report viewer. – Murilo Nov 10 '15 at 10:27
  • Good luck man, I had the same dilemma and let me warn you, there isn't much. If you find a good solution I'd love to know about it – Tyler Benzing Nov 10 '15 at 20:02
  • @UpAllNight What are the types of OrderBindingDataSet and CustomerBindingDataset? – MrZander Sep 09 '16 at 15:58
  • 1
    @MrZander They are datasets generated by the visual studio designer when you bind an object to a report viewer control. I'm sure there is a way to make them programmatically but fighting this control's desires is a losing battle. Their naming convention is a reflection of the object they bind. Notice that the format is the name of the object then `BindingDataSet` so `OrderBindingDataSet` – Tyler Benzing Sep 09 '16 at 20:21
  • @UpAllNight Thank you. RDLCs can really be a pain with POCOs – MrZander Sep 09 '16 at 21:00
1

This answer worked for me in VS2013:

http://wraithnath.blogspot.com/2011/04/reportviewer-object-datasource-nested.html

Be sure you classess fullfill with the requirements, remember add the parameterless constructor, (it only worked for me until i added the parameterless constructor)

Checklist:

  • ALL classes are serializable (every user type in the class must be serializable, and any user type in a property of a usertype must be serialzable)
  • ALL classes have a public parameterless constructor
  • ALLclasses used in the report must have the public modifier
  • If any property of the datasource, or any property of a property cannot be serialized then your will get the #Error. Just make sure everything is serializable
  • Make sure there will be no infinite recursion issues eg, class A has a property of class B, and class B has a property of class A. Use XMLIgnore / ScriptIgnore attributes

This are my classes:

[Serializable]
public class Person
{
    public Person()
    {

    }
    public string Name{ get; set; }
    public string Address1{ get; set; }
    public string Id{ get; set; }
    public string Phone { get; set; }
}

Parent:

[Serializable]
public class Header
{
    public Header()
    {

    }

    public string Product { get; set; }
    public DateTime EmisionDate{ get; set; }
    public string Number { get; set; }
    public Person Person { get; set; }
}

And this is my expression

=First(Fields!Person.Value.Name, "dsHeader")
FredE
  • 71
  • 7