Linq and CSLA

Linq and CSLA

Old forum URL: forums.lhotka.net/forums/t/8000.aspx


Damien Turnbull posted on Monday, November 16, 2009

Hi there,

Using Silverlight and CSLA 3.6, I'm attempting to bind a data grid to a ViewModel property which simply runs some Linq over a CSLA collection eg

public IEnumerable ProjContacts
{
get
{
var result = (from item in this.Model.ProjectContacts
where (Model != null && this.Model.Project != null && this.Model.Project.Id == item.Project.Id)
select item);

return result;
}
}

This all works fine and the data grid displays the correct result set. However, I'm trying to implement functionality which allows the user to add a new record to the result set (and this is where I get a little hazy).

When the user click's on the Add button to create a new row in the grid, the program is calling the CSLA collection .AddItem method, however the grid does not show the normal blank record for insert. The CSLA collection does indeed have a new record added, but in order to show the new record in the data grid I have to re-run the property containing the LINQ in order to display the newly created blank record.

So I'm wondering whether it's possible to design the solution so that the datagrid is bound to a live result set which in turn updates the CSLA collection automatically? From what I read in the book it seems possible, but I'm yet to find an example piece of code to show how.

Thanks!

RockfordLhotka replied on Monday, November 16, 2009

I suspect you are encountering a "by design" aspect of the way LinqBindingList works.

When you do an identity projection query against a BusinessListBase you get back a LinqBindingList, which is a view over the original list. This view is generated based on your query, and is continually subject to the query.

So if you add a new item to either the original list or the view, it gets added to the original list. It may or may not show up in the view depending on whether it meets the criteria of the query.

My guess is that your new item doesn't meet the conditions of the where clause, and so isn't in the view.

Damien Turnbull replied on Tuesday, November 17, 2009

I thought the same as you, that the new item's conditions may not meet the where clause's criteria. However if that was the case then wouldn't that imply that if I ran the Linq it wouldn't find this new record either?

Thanks for your help

AaronErickson replied on Tuesday, November 17, 2009

Can you clarify what you mean by "ran the Linq" - on which set?  The original, or the LBL projection?

Damien Turnbull replied on Tuesday, November 17, 2009

Sure - I'm calling an OnPropertyChanged("ProjContacts") which means the Linq is re-run against the original business collection.

Make sense?

AaronErickson replied on Tuesday, November 17, 2009

If my memory serves correctly, OnPropertyChanged:

Checks if the object should or should not belong to any indexes on an indexed property (if this is OnPropertyChanged of an indexed property)

Checks to see if it is still an appropriate member of each attached LBL.

I do not believe it does any query re-execution.  There may in fact be an error where changes in a child object (i.e. from the BLB or a different LBL) do not invoke a recheck to make sure it should still be in all the LBLs (changing a property if it was a predicate in a query should, in theory, make sure it is still a member of all queries with the relevant membership predicates).

A good way to isolate it is to take it out of the context of a form.  Write a test where you create a BLB, derive two LBLs based on one of the properties, change a property of one of the LBLs that should remove it's membership in the other one, and assert that the membership is removed.

I am in the midst of building my 4.0 VM at the moment, so you may have to do this yourself until I have everything up and running.

The LBL and the BLB reference exactly the same object, so property changes are not synced there.

Copyright (c) Marimer LLC