wesmantooth
wesmantooth

Reputation: 625

Issue binding foreign key objects from EF POCO to WinForm control

I have 3 entities coded into my application: Account, Product, Purchase

The Purchase object has an Account and a Product, then a few other standard data types (Revenue, Date, Quantity, etc)

[System.Data.Linq.Mapping.Table(Name = "Purchases")]
public class Purchase
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long PurchaseId { get; set; }

    public Account Account { get; set; }

    public Product Product { get; set; }

    public DateTime PurchaseDate { get; set; }

    public decimal Revenue { get; set; }

    public long Quantity { get; set; }
}

The Account object has an ObservableCollection, and I envisioned accessing purchases and binding to controls like this:

Account acct = db.Accounts.First(a => a.AccountId == 1);

this.dataGridView1.DataSource = acct.Purchases.ToBindingList();

The only problem is that the DataGrid column for Account and Product are not populating as expected. I get a weird Proxy version of Account, and Product is blank. See below:

DataGridPng

1) What do I need to do so that the Account column is populated with the AccountId and Product column gets ProductId (Or better yet a different property like ProductName)?

2) It seems like straight binding of EF objects to controls using .ToBindingList() (demonstrated here http://msdn.microsoft.com/en-us/data/jj682076.aspx) is extremely limited. For instance, can you bind certain columns and exclude others? What about this scenario when you use an object that aggregates other objects? Most of the databinding samples I've seen are pretty basic, and I'm unsure if this approach is going to meet my requirements. Do you have any advice / resources for complex control binding?

Upvotes: 1

Views: 184

Answers (1)

Yuliam Chandra
Yuliam Chandra

Reputation: 14640

You can override the ToString method on the related entity, could be in the partial class or in the main class.

public partial class Product
{
    public override string ToString()
    {
        return ProductName;
    }
}

Or you can also use Select to choose which column to display.

var purchases = acct.Purchases.Select(p => new 
{
    p.PurchaseId,
    Account = p.Account.AccountName,
    Product = p.Product.ProductName,
    p.PurchaseDate
});
var source = new ObservableCollection<object>(purchases).ToBindingList();
this.dataGridView1.DataSource = source;

Upvotes: 1

Related Questions