none
Odd Behaviour RRS feed

  • Question

  • Hi,

    I have an interesting situation with some LINQ-to-SQL code. I have a simple object with three properties. I change two of them and issue SubmitChanges. I get two different behaviours.

    In my test code the update works successfully and the correct SQL is issued. When I call the method from the application only one of the two properties are changed and the update SQL only updates one of the columns. If I change only the data in the 'buggy' property then no Update is issued to the database, but when I only change this property in the test it does!

    I debug my code and right up until the SubmitChanges the 'buggy' property has the correct updated value. After the call to SubmitChanges the property reverts back to the original value.

    Has anyone seen this before?

    I can post code if you need it.

    James :-)
    Wednesday, December 9, 2009 8:27 AM

All replies

  • Are you by any chance trying to change a member that is [marked as] part of the primary key for your entity?
    Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools (add-in with new features for Visual Studio 2008's L2S and EF designers)
    huagati.com/L2SProfiler (Query profiler for Linq-to-SQL and LLBLGen Pro)
    Wednesday, December 9, 2009 9:28 AM
    Answerer
  • Please paste your code here, so I can have better Idea. and also with value which are you use to update test.

    Tejas Mer
    Wednesday, December 9, 2009 9:31 AM
  • No,

    I am changing a member that is a foreign key that does exist.

    Another issue is that when I create a new object and then issue submit changes it works fine. When I try to issue another one it tries to reissue the first create to the database. Should I reinstantiate the context after every time I call submit changes or is there something else I should be doing?

    James :-)
    Wednesday, December 9, 2009 9:34 AM
  • public sealed class ResourceServiceUpdateResourceRequest
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int OrgUnitId { get; set; }
        }

    internal class ResourceServiceUpdateResourceAdapter
        {
            ResourceServiceUpdateResourceRequest _updated;
            Resource _original;

            public ResourceServiceUpdateResourceAdapter(ResourceServiceUpdateResourceRequest updated,
                                                        Resource original)
            {
                this._updated = updated;
                this._original = original;
            }

            public void Fill()
            {
                this._original.Fullname = this._updated.Name;
                this._original.UnitId = this._updated.OrgUnitId;

                return;
            }
        }

    public class ResourceService : IResource, IDisposable
        {
    public ServicesCUResponse Update(ResourceServiceUpdateResourceRequest resource)
            {
                ServicesCUResponse response = GetCUResponse();

                try
                {
                    Resource original = LoadResourceFromPersistence(resource.Id);
                    ResourceServiceUpdateResourceAdapter adapter = new ResourceServiceUpdateResourceAdapter(resource,
                                                                                                            original);
                    adapter.Fill();

                    this._context.SubmitChanges();
                }
                catch (InvalidOperationException)
                {
                    response.Success = false;
                    response.Errors.Add(CommonMessages.RecordDeleted);
                }
                catch (Exception ex)
                {
                    response.Success = false;
                    response.Errors.Add(ex.Message);
                }
                finally
                {
                    this._context = new UsageDataContext();
                }

                return response;
            }
    }



    The following is a test case that works:

    /// <summary>
            ///A test for Update
            ///Checks for changes to both Org Unit and Fullname
            ///</summary>
            [TestMethod()]
            public void UpdateTest()
            {
                ResourceService_Accessor target = new ResourceService_Accessor();
                ResourceServiceUpdateResourceRequest resource = new ResourceServiceUpdateResourceRequest() { Id = 2, Name = "Updated Resource", OrgUnitId = 3 };
     
                ServicesCUResponse actual;
                actual = target.Update(resource);
                Assert.IsTrue(actual.Success, "Success");

                Resource updated = target.LoadResourceFromPersistence(resource.Id);

                Assert.AreEqual(updated.Id, resource.Id, "Id");
                Assert.AreEqual(updated.UnitId, resource.OrgUnitId, "Org Unit Id");
                Assert.AreEqual(updated.Fullname, resource.Name, "Name");
            }

    The following is the code in the presenter that doesn't:

    public void Update()
            {
                ResourceServiceUpdateResourceRequest resource = new ResourceServiceUpdateResourceRequest();
                resource.Id = this._view.ResourceId;
                resource.Name = this._view.Fullname;
                resource.OrgUnitId = this._view.OrgUnitId;

                ServicesCUResponse response = this._resourceService.Update(resource);

                if (!response.Success)
                {
                    this._view.SetErrors(response.Errors);
                }
                else
                {
                    LoadResources();
                    this._view.SelectedResource = new ResourceServiceGetResourcesResponse() { Id = resource.Id, FullName = resource.Name, OrgUnitId = resource.OrgUnitId };
                }
            }

    When I look at the variables at a break point at sumbit changes it shows the vales that were passed into the service layer from  the presentation layer, but after submit changes only Resource.Name is changed. In the Unit Test both Resource.Name and Resource.UnitId are changed.

    James :-)
    Wednesday, December 9, 2009 9:35 AM
  • Ah, it seems that if the create fails the object remains in the LINQ-to-SQL cache and the next time a SubmitChanges is issued it tries to add it again as it is still seen as a change. I guess I have to remove it or reinstantiate the context...... Guess I have been working on the web for too long so that I have forgetten things can have a lifetime greater than a postback :)
    Wednesday, December 9, 2009 9:42 AM