Refetch doesn't refresh when deleting from related collection

Posts   
 
    
Eddie1506
User
Posts: 9
Joined: 21-Nov-2007
# Posted on: 04-Jan-2008 18:45:39   

LLBLGen Pro version: 1.0.2005.1 .NET Framework 1.1 SP1, C# SelfServicing, two class scenario SQL Server Express 2005

Okay, I have a Subscription table which is related to Performance table via m:n relation using SubscriptionPerformance.

In a form, Subscription collection is bound to a listbox. There is a master detail view that shows some data from each Performance entity from currently selected Subscription.

If I want to edit Performance collection, I'm using a new form.

When I close that form i want to display refreshed data for currently selected Subscription.


subscription = (NetgenTheatron.EntityClasses.SubscriptionEntity) this.cmSubscriptions.Current;
subscription.AlwaysFetchPerformanceCollectionViaSubscriptionPerformance = true;
subscription.Refetch();

Then I go through every Performance entity in PerformanceCollectionViaSubscriptionPerformance and adding data to master detail view.


foreach(NetgenTheatron.EntityClasses.PerformanceEntity performance in subscription.PerformanceCollectionViaSubscriptionPerformance)
{
   this.lblPerformanceList.Text += performance.Name + " (" + performance.Date + ")\n\n";
}

This works OK if I add Performance entities to the collection, but not when deleting from it.

When deleting, the master detail view remains the same, and when I try to open the form for editing Performance collection I get an exception saying "This entity is deleted from the database and can't be used in logic." It doesn't happen when I'm adding entities to Performance collection.

Any help? Thanks!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 06-Jan-2008 11:02:20   

the M:N collection is readonly, so if you remove a Performance entity, it's not removed from that collection.

What I'd do is clear the Performance collection from the Subscription, and simply refetch the m:n collection.

Or I might not fully understand the situation, so if this won't work, please correct me simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Eddie1506
User
Posts: 9
Joined: 21-Nov-2007
# Posted on: 06-Jan-2008 18:46:59   

Well, I'm not actually deleting and adding Performance entites, just editing their relation to Subscription entity.

So when I add or delete relation of Performance entity to Subcription entity, this is what I'm doing.


transactionManager.Add(subscription);

foreach(NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp in subscription.SubscriptionPerformance)
{
transactionManager.Add(sp);
sp.Delete();
}

foreach(NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp in this.subscriptionPerformanceColl)
{
NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity spNew = new NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity();
spNew.IDPerformance = sp.IDPerformance;
spNew.IDSubscription = sp.IDSubscription;
subscription.SubscriptionPerformance.Add(spNew);
}

subscription.Save(true);
transactionManager.Commit();

subscriptionPerformanceColl is a temporary collection of SubscriptionPerformance entities. I fill it with entities from subscription.SubscriptionPerformance when the form used for editing is open. Then I add or delete entites to and from subscriptionPerformanceColl and then use the above code to replace existing subscription.SubscriptionPerformance with my temp collection.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 07-Jan-2008 04:23:19   

Could you please post the code where you delete any entity at the edit window?

David Elizondo | LLBLGen Support Team
Eddie1506
User
Posts: 9
Joined: 21-Nov-2007
# Posted on: 07-Jan-2008 09:57:46   

Initial creating of subscriptionPerformanceColl when form loads.


foreach(NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp in subscription.SubscriptionPerformance)
{
NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp2 = new NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity();
sp2.IDPerformance = sp.IDPerformance;
sp2.IDSubscription = sp.IDSubscription;
subscriptionPerformanceColl.Add(sp2);
}

Adding relation Performance - Subscription


NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity subscriptionPerformance = new NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity();

subscriptionPerformance.IDSubscription = subscription.IDSubscription;
subscriptionPerformance.IDPerformance = (int) listBoxPerformances.SelectedValue;

subscriptionPerformanceColl.Add(subscriptionPerformance);

Removing relation Performance - Subscription


CurrencyManager cm = (CurrencyManager)this.BindingContext[this.dataGridSubscriptionPerformances.DataSource];

if(cm.Position != -1)
{
NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp = (NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity) cm.Current;

subscriptionPerformanceColl.Remove(sp);
}

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 07-Jan-2008 10:26:26   

subscription = (NetgenTheatron.EntityClasses.SubscriptionEntity) this.cmSubscriptions.Current; subscription.AlwaysFetchPerformanceCollectionViaSubscriptionPerformance = true; subscription.Refetch();

Instead of using the above code, you should fetch a new Subscription entity with the appropriate prefetchPaths, and replace the current entity with the newly fetched one.

Eddie1506
User
Posts: 9
Joined: 21-Nov-2007
# Posted on: 07-Jan-2008 11:05:22   

Thanks for the tips. I found a way to do it with the code from my second post.

transactionManager.Add(subscription); subscription.PerformanceCollectionViaSubscriptionPerformance.Clear(); subscription.SubscriptionPerformance.Clear();

foreach(NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp in subscription.SubscriptionPerformance) { transactionManager.Add(sp); sp.Delete(); }

foreach(NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity sp in this.subscriptionPerformanceColl) { NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity spNew = new NetgenTheatron.EntityClasses.SubscriptionPerformanceEntity(); spNew.IDPerformance = sp.IDPerformance; spNew.IDSubscription = sp.IDSubscription; subscription.SubscriptionPerformance.Add(spNew); }

subscription.Save(true); transactionManager.Commit();

Now, which is the better way? Using prefetch paths, or this one, to force clearing SubscriptionPerformance and PerformanceCollectionViaSubscriptionPerformance and then refetching using Refetch()?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 07-Jan-2008 11:08:20   

Either will do, I thought about the clearing solution too simple_smile So, I think you may stick with it.

Eddie1506
User
Posts: 9
Joined: 21-Nov-2007
# Posted on: 07-Jan-2008 11:14:35   

Thanks all for your help! simple_smile