Bind a grid to an anonymous LINQ result, then commit changes to DB?
I've been looking into how best to do this and wisdom would be appreciated. For read only purposes, I've been happily using LINQ and binding it to a grid. For editing purposes, I've used the LinqDataSource control, enabled the Edit/Delete operations in the process, and I have a nice editable grid bound to some or all of the table's fields.
Now I have a situation where I want to edit a few fields in table A, but there are various values in linked table B that I want to display in that grid too (no editing of those). So my query looks like the below. The fields in tblDupes (cleared, notes) are what I want to edit, but I'd like to display those tblVoucher ones.
var theDupes = from d in db.tblDupes
where d.dupeGroup == Ref
select new
{
Ref = d.dupeGroup,
InvoiceNum = d.tblVoucher.invoiceRef,
Value = d.tblVoucher.invoiceAmtDecimal,
VendorNum = d.tblVoucher.vendorID,
VendorName = d.tblVoucher.vendorName,
Cleared = d.Cleared
Notes = d.Notes
};
A similar but different question LINQDataSource - Query Multiple Tables? sent me looking at scott Guthrie's blog entry http://weblogs.asp.net/scottgu/archive/2007/09/07/linq-to-sql-part-9-using-a-custom-linq-expres开发者_StackOverflowsion-with-the-lt-asp-linqdatasource-gt-control.aspx, where he handles various events to have a LinqDataSource with a custom query across tables. This still seems aimed at explicitly designed classes though, even if the class has only a subset of the fields.
So my question is: is there an easy way to allow committing of the changes made to the anonymous collection (a changes.Submit type action), or just an easy way to 'display' fields from another table while not involving them in the updating?
EDIT: Thinking more, it doesn't have to be anonymous really. I'd be happy to define a class to contain the elements in that query, since it won't change often. But, those elements would be across two tables, even though only one needs updating. Not sure if that suggests entity framework would be more suitable - I get the feeling it wouldn't - I don't want the whole 'model' always grouping the fields in this way.
Thanks!
Taking a wild guess here, but couldn't you listen to the LINQDataSource.Updating event and perform your save there? You would, of course, have some problems with the mapping since you cannot type the object
in the LinqDataSourceUpdateEventArgs.OriginalObject
.
What if you create a ViewModel instead of the anonymous type. Something like DupeVoucherViewModel
.
Then in the Updating
event, you could cast the LinqDataSourceUpdateEventArgs.OriginalObject
to the DupeVoucherViewModel
object and start mapping and saving your data.
Example
Given that you create a view model (a class) that you call DupeVoucherViewModel
and bind to that like so:
var theDupes = from d in db.tblDupes
where d.dupeGroup == Ref
select new DupeVoucherViewModel
{
Ref = d.dupeGroup,
InvoiceNum = d.tblVoucher.invoiceRef,
Value = d.tblVoucher.invoiceAmtDecimal,
VendorNum = d.tblVoucher.vendorID,
VendorName = d.tblVoucher.vendorName,
Cleared = d.Cleared
Notes = d.Notes
};
Then the server tag should map the updating event like so:
<asp:LinqDataSource EnableUpdate="true" OnUpdating="LinqDataSource_Updating" />
And the code behind should contain the following method:
protected void LinqDataSource_Updating(object sender, LinqDataSourceUpdateEventArgs e)
{
// originalObject contains the unchanged object
var originalObject = (DupeVoucherViewModel)e.OriginalObject;
// newObject contains the changed object
var newObject = (DupeVoucherViewModel)e.NewObject;
// Perform your save using newObject
yourDataAccessComponent.SaveSomething(newObject);
}
You might need to include some more information in the DupeVoucherViewModel
such as an ID of tblDupes or something, so that you can load that and change it.
You can read more about the LinqDataSource here: http://msdn.microsoft.com/en-us/library/bb514963.aspx
精彩评论