Skipping the details, heres the code binding to a linq query:
users.LinqContext = new UserDataContext();
users.ItemsSource = from i
in users.DataSource<User>()
select i;
And this code fully supports inserts/updates/deletes.
The implementation lives inside the DataSource<User>() call. This devious character returns a reference to a IBindingList (which supports the table modifications) and implements IQueryable (to support linq queries).
What about inheritance?
Imagine you had a sub class called SuperUser; if you've played with linq inheritance you'll know that you have to use the base type User to actually do anything. It's kind of a pain, and you get real friendly with the .OfType<>() call.
So here's the code again, this time selecting all SuperUsers.
users.ItemsSource = from i
in users.DataSource<User, SuperUser>()
select i;
Can I use .Take(x)?
As far as I can tell, all the standard linq statements are supported (including aggregate operators). I haven't looked into partial classes and anonymous types, though I doubt they'd work well.
I won't go into the laborious details of how it's all implemented, just know that it's been fun playing with linq expression trees and writing my own IQueryProvider.
If you are interested, the code can be found here.
I haven't seen anything quite like this out there, so if you have some opinions - I'd love to hear some feedback.
13 comments:
Quick Q - apologies for the laziness :)
Why are you rewriting the expression tree?
I'm not actually rewriting the expression tree, rather injecting and wrapping it.
This way I can return my own BindingList (which supports inserts/updates/deletes) instead of the direct database collection.
Luke,
Have you ever tried your solution with groupings?
If so, did you manage to insert new rows without any errors?
I keep getting an unhandled DataGridInternalError. I think it occurs when the layout gets refreshed, cause all data inserted well.
Any help or ideas would be appreciated.
Great question Anthony!
I haven't tried it with the linq "group by" - but I don't think it would work well (considering two-way binding).
However I have successfully used the ICollectionView grouping features.
Which one are you trying? or have you another option?
Luke,
It works, I found was I was doing wrong.
My grid is not enabled, additions and changes are managed by a detailed page with fields binded to the currentitem in the grid.
What I forgot was setting the insertionrow in the fixedheaders.
Problem solved.
Thanks for your response.
Glad to hear you got it working.
Cheers!
how can add validation ?
every time i validate its break down at endedit
i cant insert new records
the cell is disabled
what is wrong :(
Hi anonymous!
For validation I would suggest using the Xceed validation classes (since IDataErrorInfo is not supported yet).
The validation classes throw exceptions at EndEdit, but if you ignore this the validation error kicks in.
As for the disabled cell, I really can't help without more information.
Oh and change this in DataBindingList.cs to fix a small bug.
protected override void RemoveItem(int index)
{
if (((index >= 0) && (index < base.Count)) && (base[index] == this.cancelNewInstance || base[index] == this.addNewInstance))
{
this.addNewInstance = default(TEntity);
this.cancelNewInstance = default(TEntity);
}
else
{
this.table.DeleteOnSubmit(base[index]);
}
base.RemoveItem(index);
}
hi
i am using xceed validation that throw exception but after that endedit fail at LinqDataRow class
thanks
Luke,
Sorting not working
Not sure what's wrong with your validation - it seems to work fine for me.
Yes sorting isn't working, feel free to have a crack at it!
I stopped updating this code about a year ago when I found BindableLinq - I'm not sure if it's a complete replacement, but it looks pretty good!
Post a Comment