New Posts New Posts RSS Feed: Silverlight 5 bug when saving twice in a row
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Silverlight 5 bug when saving twice in a row

 Post Reply Post Reply
Author
macgajos View Drop Down
Newbie
Newbie


Joined: 16-Feb-2012
Posts: 4
Post Options Post Options   Quote macgajos Quote  Post ReplyReply Direct Link To This Post Topic: Silverlight 5 bug when saving twice in a row
    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();
});


Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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.
Back to Top
macgajos View Drop Down
Newbie
Newbie


Joined: 16-Feb-2012
Posts: 4
Post Options Post Options   Quote macgajos Quote  Post ReplyReply Direct Link To This Post 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
Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down