Print Page | Close Window

Silverlight 5 bug when saving twice in a row

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3374
Printed Date: 17-Sep-2025 at 1:12am


Topic: Silverlight 5 bug when saving twice in a row
Posted By: macgajos
Subject: Silverlight 5 bug when saving twice in a row
Date Posted: 04-Apr-2012 at 8:23am
Hi, I've found a bug  in dev force for Silverlight 5. Please find the following function:

public void SetDesignSlotImage(DesignSlotImage designSlotImage, byte[] imageData, Action callback)
{
            // imageData is != null

            if (designSlotImage.ImageId != null)
            {
                designSlotImage.Image.EntityAspect.Delete();
                designSlotImage.Image = null;
            }

            designSlotImage.Image = new DomainModel.Image()
            {
                ImageData = imageData,
            };

            //Breakpoint 1
            SaveChanges(myManager, () =>
                {
                    //Breakpoint 2
                    callback();
          });
}

DesignSlotImage is a DB entity. 
Image is a DB entity.
The relationship is 0..1 to  many. Image has no navigation property for DesignSlotImage images. DesignSlotImage has nullable ImageId property and Image property.

If You run this method once, everything is ok. Unfortunately every two executions weird stuff happens:

Breakpoint 1 
designSlotImage.Image  is as it should be
Breakpoint 2 
designSlotImage.Image is detached, designSlotImage.ImageID is ok

as a result , third execution of the method will not remove an Image.

Reproduce?
Run 
SetDesignSlotImage(myDesignSlotImage, imageData, () =>{});
SetDesignSlotImage(myDesignSlotImage, imageData, () =>{});

Walkaround?
After saving changes manually assign image from cache:

SaveChanges(_persistenceGateway.LayoutsManager, () =>
{

designSlotImage.Image = 
myManager.Images.With(QueryStrategy.CacheOnly).First(p => p.Id == designSlotImage.ImageId);

//Note that myManager.HasChanges returns false at this point 

callback();
});





Replies:
Posted By: sbelini
Date Posted: 09-Apr-2012 at 4:16pm
Hi macgajos,
 
This doesn't seen like a bug.
 
What is happening is that you are calling SetDesignSlotImage twice and the method itself performs a save (which occurs async). So the second time aroud, the entities still haven't been saved, but have already been modified.
 
Your simplified code using NorthwindIB:
 
void MainPage_Loaded(object sender, RoutedEventArgs e) {
  _mgr.Orders.AsScalarAsync().First(orderOp => {
    var order = orderOp.Result;
    if (order.EmployeeID != null) {
      order.Employee.EntityAspect.Delete();
      order.Employee = null;
    }
 
    order.Employee = new Employee() { FirstName = "Silvio1", LastName = "Belini1" };
 
    _mgr.SaveChangesAsync(savedArgs1 => {
      if (savedArgs1.CompletedSuccessfully) {
        MessageBox.Show("saved ok");
      } else {
        MessageBox.Show(savedArgs1.Exception.Message);
      }
    });
 
    // second time around
 
    if (order.EmployeeID != null) {
      order.Employee.EntityAspect.Delete();
      order.Employee = null;
    }
    order.Employee = new Employee() { FirstName = "Silvio2", LastName = "Belini2" };
    _mgr.SaveChangesAsync(savedArgs2 => {
      if (savedArgs2.CompletedSuccessfully) {
        MessageBox.Show("saved ok");
      } else {
        MessageBox.Show(savedArgs2.Exception.Message);
      }
    });
  });
}
 
What exactly are you trying to accomplish by modifying the same entity twice, the second time being while the first SaveChanges call is still pending?
 
Regards,
   Silvio.


Posted By: macgajos
Date Posted: 10-Apr-2012 at 11:10pm
Hi Silvio,

Of course my 'Reproduce' sample is invalid, it was supposed to look like this:

SetDesignSlotImage(myDesignSlotImage, imageData, () =>
{
SetDesignSlotImage(myDesignSlotImage, imageData, () =>{});
});

Sorry for confusion.

Regards,
Maciej


Posted By: sbelini
Date Posted: 11-Apr-2012 at 12:50pm
Hi Maciej,
 
I reproduced the issue. The problem is that when you call:
 
designSlotImage.Image.EntityAspect.Delete();
 
The Image.EntityAspect.EntityState should change to Deleted rather then detached (i.e. assuming that the previous EntityState is Unchanged/Modified)
 
I actually verified the issue in both SL4 and SL5. I'll be filing a bug for this.
 
By the way, instead of checking:
 
if (designSlotImage.ImageId != null)
 
You should do:
 
if (!designSlotImage.ImageId.EntityAspect.IsNullOrPendingEntity)
 
You shouldn't rely on the FK having null value (while that might work for a Guid, it won't for an int)
 
Silvio.



Print Page | Close Window