This is a migrated thread and some comments may be shown as answers.

SaveChanges() losing changes, not applying changes to database

4 Answers 152 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Roger
Top achievements
Rank 1
Roger asked on 04 Nov 2010, 04:56 PM
I'm using the new domain model for my application, and so far I like it.  I'm having a huge problem right now, though, where it appears that data is getting lost on the update.

I'm using the DataManager class that Telerik provides.  My update service call looks like this:

public void UpdatePattern(Pattern modelPattern)
{
    using (var context = new DataManager(new DAL.MyContext()))
    {
        var dataPattern = new DAL.Pattern { ModifiedDate = DateTime.Now };
 
        this.MapPatternModelToData(modelPattern, dataPattern);
 
        context.UpdateEntity(dataPattern);
    }
}

The Telerik code for UpdateEntity looks like this:

public string UpdateEntity<T>(T entity)
{
    try
    {
        IObjectId id = Database.OID.GetObjectId(entity);
        T existingEntity = _openAccessContext.GetObject<T>(new ObjectKey(id));
        this.ExecuteCopy(entity, existingEntity);
        this._openAccessContext.SaveChanges();
 
        return id.ToString();
    }
    catch (OpenAccessException)
    {
        this._openAccessContext.ClearChanges();
        throw;
    }
}

The ExecuteCopy() method is correctly copying the data to the 'existingEntity' but somehow SaveChanges() is dropping the changes on the way to the database.  For example, I had changed the value of TypeId but, as you can tell from my profiler, the TypeId (@p5) is set to NULL:

declare @p1 int
set @p1=7
exec sp_prepexec @p1 output,N'@p0 int,@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int,@p6 uniqueidentifier,@p7 int,@p8 uniqueidentifier',N'UPDATE [Pattern] SET [Measurement1Id]=@p0, [ModifiedDate]=@p1, [Measurement2Id]=@p2, [RangeId]=@p3, [FeatureId]=@p4, [TypeId]=@p5, [UniqueId]=@p6 WHERE [PatternId] = @p7 AND [Measurement2Id] is null AND [Measurement1Id] is null AND [RangeId] is null AND [FeatureId] is null AND [TypeId] is null AND [UniqueId]=@p8',@p0=NULL,@p1='2010-11-04 08:13:43:993',@p2=NULL,@p3=NULL,@p4=NULL,@p5=NULL,@p6='00000000-0000-0000-0000-000000000000',@p7=10,@p8='91958B38-DE5A-4E5A-B763-5316EB4EBB7D'
select @p1

What would cause this to happen?

4 Answers, 1 is accepted

Sort by
0
Roger
Top achievements
Rank 1
answered on 04 Nov 2010, 05:16 PM
Looking at it a little further, I can guess that it has something to do with the persistent entity that is generated with it.  Since I am only setting the FK ID for that entity, and the persistent entity is null, the call is using the null entity instead of the FK ID that I'm providing.  But it seems to me that, using the old methods (e.g. IObjectScope), a Commit() would look at both the FK ID and the entity and decide to take the one that had data.  Is that impression wrong?

So, if my deduction here is correct, what's the proper way to attach the persistent entity, given the FK ID?
0
Jan Blessenohl
Telerik team
answered on 04 Nov 2010, 05:24 PM
Hi Roger,
What is executecopy doing? If you copy the values directly into the fields via reflection it will not work because we cannot make the object dirty.

Best wishes,
Jan Blessenohl
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Roger
Top achievements
Rank 1
answered on 04 Nov 2010, 06:00 PM
ExecuteCopy() is part of the DataManager class that the DSW produces (though I'm not using the DSW).  As you say, it copies directly into the fields via reflection, but it copies into an enhanced object--the object is retrieved using the OpenAccessDataContextBase.GetObject<T>(ObjectKey) method--so it looks like IsDirty is getting set correctly.

How can I tell if an object is enhanced?  Is there something like a GetIsPersisted() method or IsEnhanced property that can be called on an entity?

And my original question still stands:  Why doesn't the data context notice that a change has occurred on the ID field and use that, instead of defaulting to the null entity field?
0
A.Alexandrov
Telerik team
answered on 16 Nov 2010, 07:43 PM
Hi Roger,

Unfortunately we were unable to reproduce the problem on our side. At this stage I will have to ask you to send us your project so we can debug it locally.
Regarding the ExecuteCopy method, this should not be the problem. It updates the object's properties, which on their side set the dirty flag to true. You can verify this using the following code:
 
var result = obj.GetType().GetMethod("OpenAccessEnhancedIsDirty").Invoke(obj, new object[] { propertyName });
where propertyName is the name of the property that you want to check before calling SaveChanges().

Kind regards,
A.Alexandrov
the Telerik team
See What's New in Telerik OpenAccess ORM in Q3 2010!
Monday, November 15, 11 am Eastern Time: Register here>>
Monday, November 15, 10 pm Eastern Time: Register here>>
Tags
Development (API, general questions)
Asked by
Roger
Top achievements
Rank 1
Answers by
Roger
Top achievements
Rank 1
Jan Blessenohl
Telerik team
A.Alexandrov
Telerik team
Share this question
or