Struggling with EditableRootList object and LINQ to SQL

Struggling with EditableRootList object and LINQ to SQL

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


triplea posted on Monday, August 11, 2008

I am struggling to implement a simple EditableRootList object using CSLA 3.5. Lets say I have the following:

CustomerList : BusinessListBase<CustomerList, Customer> (Root)
Customer: BusinessBase<Customer>

There are some LINQ to SQL related questions embedded below so its not pure CSLA related but help is appreciated nevertheless :-)

1. When fetching Customer objects in the DataPortal_Fetch of CustomerList, should I be adding the items like this:
this.Add(Customer.GetCustomer(data));
or
this.Add(DataPortal.FetchChild<Customer>(data));
or another way?
Data is my LINQ to SQL var.

2. In the above scenario, when using the first way, I can jump to other related tables (e.g. customer invoices table) when I am in the Child_Fetch method of Customer. If I use the second way, these related tables throw an System.ArgumentException.

3. What is the Update method supposed to look like? I was hoping I wouldn't have to implement it (in the same way that Editable Child Lists dont really implement the Update method anymore) but that does not seem to be the case.

All in all I am not used to use EditableRootLists and am a bit unsure if items witihn the list are supposed to be child objects or not...

RockfordLhotka replied on Tuesday, August 12, 2008

triplea:

1. When fetching Customer objects in the DataPortal_Fetch of CustomerList, should I be adding the items like this:
this.Add(Customer.GetCustomer(data));
or
this.Add(DataPortal.FetchChild<Customer>(data));
or another way?
Data is my LINQ to SQL var.

The idea in 3.5 is to use FetchChild() so the data portal can do more work for you. But the old-style approach continues to work as long as you do your own MarkOld() calls, etc.

'data' isn't the full query result though right? You'd be in a foreach loop at this point - looping through the query result, so 'data' is just ONE ITEM from the query result.

triplea:

2. In the above scenario, when using the first way, I can jump to other related tables (e.g. customer invoices table) when I am in the Child_Fetch method of Customer. If I use the second way, these related tables throw an System.ArgumentException.

I don't know why that would be the case. Either way the parameter is passed to the new child object, and either way you'd need to know the type of 'data'. As long as your L2S data context is still alive I would expect either approach to work.

However, FetchChild() does invoke the Child_Fetch() method using reflection, so perhaps L2S gets confused by that?

triplea:

3. What is the Update method supposed to look like? I was hoping I wouldn't have to implement it (in the same way that Editable Child Lists dont really implement the Update method anymore) but that does not seem to be the case.

An editable child list doesn't need Child_Update(), because CSLA can do it for you.

An editable root list does need DataPortal_Update() because I don't know how to open your database. You must open the database (or L2S data context), but then you can call base.Child_Update() and let CSLA do most of the work for you:

protected override void DataPortal_Update()
{
  // open database
  base.Child_Update(this);
  // close database
}

triplea:

All in all I am not used to use EditableRootLists and am a bit unsure if items witihn the list are supposed to be child objects or not...

BLB and ERLB are very different.

BLB supports the editable root list and editable child list stereotypes. These do updates in a batch - so the user edits many objects in memory, and they are all saved in one data portal call.

ERLB supports the dynamic root list stereotype. This is a list of editable root objects with a twist. It contains editable root objects that are fetched somewhat like child objects, and are saved like root objects. As the user completes interacting with each individual object, that object is immediately saved.

ERLB is designed specifically to support in-place editing with a Windows Forms grid. While it might work in other scenarios, it is designed specifically for the Windows Grid and in-place editing, where the user's changes are committed immediately as the user moves off each row.

triplea replied on Tuesday, August 12, 2008

Thanks a lot for your input!

RockfordLhotka:

'data' isn't the full query result though right? You'd be in a foreach loop at this point - looping through the query result, so 'data' is just ONE ITEM from the query result.

Yes thats exactly right, data is only 1 item which is extracted using a foreach loop.

RockfordLhotka:

As long as your L2S data context is still alive I would expect either approach to work.

How could I ensure that the data context is still alive when I get into the Child_Fetch()? Do I need to use the transactional attribute or manually do something else?

Also thanks for the BLB/ERLB clarification. In my case I use a BLB as an editable root list.

 

ajj3085 replied on Tuesday, August 12, 2008

You should look into the Csla.Data.ContextManager.  If your root BLB base, your DP_U would look like this:

[Transactional( Transaction.TransactionScope )]
protected override DataPortal_Update() {
     ContextManager<MyDataContext> mgr;

     using( mgr = ContextManager<MyDataContext>.GetManager() {
         // do child updates
     }
}

In your child object, you get a ContextManager in the same way, and you'll get the one that your root object created.

HTH
Andy

RockfordLhotka replied on Tuesday, August 12, 2008

If you use Csla.Data.ContextManager then keeping the context alive is just a matter of loading all your child objects inside the using block.

 

using (var ctx = ContextManager<MyDatabase>.GetManager(“dbName”))

{

  // load root and all children here

}

 

Rocky

triplea replied on Tuesday, August 12, 2008

Not sure if I was too tired or if I changed anything without noticing but the 
this.Add(DataPortal.FetchChild<Customer>(data));
way seems to be working now...

Thanks for both your help

Copyright (c) Marimer LLC