Data Access has been discontinued. Please refer to this page for more information.

Accessing Original Values After Changes

Telerik Data Access allows you to get the original property values for a tracked model entity. The original values are usually the entity's property values as they were before any changes. The original property values could be obtained by using the generic OpenAccessContext.GetOriginalValue<T> method. The method accepts two parameters. The first one is the object that holds the property or field of interest. The second parameter is a string containing the name of the property for which you want to retrieve the original value. Once you call the SaveChanges method, the original property value will be replaced with the one that you have already committed to the database.

The following example illustrates how to use the GetOriginalValue method to retrieve the original value of the Price and Make properties.

using (FluentModel dbContext = new FluentModel())
{
   Car car = dbContext.Cars.FirstOrDefault();
   // Make some changes.
   car.Make = "NewMake";
   car.Model = "NewModel";
   car.Rating = 2;

   string originalMakeValue = dbContext.GetOriginalValue<string>(car, "Make");
   decimal originalRatingValue = dbContext.GetOriginalValue<decimal>(car, "Rating");
}
Using dbContext As New FluentModel()
 Dim _car As Car = dbContext.Cars.FirstOrDefault()
 ' Make some changes.
 _car.Make = "NewMake"
 _car.Model = "NewModel"
 _car.Rating = 2

 Dim originalMakeValue As String = dbContext.GetOriginalValue(Of String)(_car, "Make")
 Dim originalRatingValue As Decimal = dbContext.GetOriginalValue(Of Decimal)(_car, "Rating")
End Using

If the property name you are passing to the GetOriginalValue method is not found, a new InvalidOperationException will be thrown.

The GetOriginalValue method works on reference properties and collections as well. However, in the case of a reference property, there is one significant detail. In order to get the original value, you need to have an actual change to the reference itself, not a change of a property in the referenced object. The following example demonstrates the correct usage of the GetOriginalValue method in the case of a reference property.

using (FluentModel dbContext = new FluentModel())
{
   Car car = dbContext.Cars.FirstOrDefault();    
   car.Category = dbContext.Categories.LastOrDefault();
   Category originalCarCategory = dbContext.GetOriginalValue<Category>(car, "Category");
}
Using dbContext As New FluentModel()
 Dim _car As Car = dbContext.Cars.FirstOrDefault()
 _car.Category = dbContext.Categories.LastOrDefault()
 Dim originalCarCategory As Category = dbContext.GetOriginalValue(Of Category)(_car, "Category")
End Using

By default, the GetOriginalValue method will work only in the cases when you are using the changed concurrency control. The GetOriginalValue method will not work out of the box when you have either Version or None concurrency control. In these cases you will have to set the MaintainOriginalValues property to true. This property is accessible through the OpenAccessContextOptions object that is exposed by the OpenAccessContext.

using (FluentModel dbContext = new FluentModel())
{
   dbContext.ContextOptions.MaintainOriginalValues = true;
}
Using dbContext As New FluentModel()
 dbContext.ContextOptions.MaintainOriginalValues = True
End Using

This will allow Telerik Data Access always to retrieve the old values of your properties before settings new ones. Note that this might be a performance issue for your application as an additional query will be generated for obtaining the original value of the property you are about to change. If you attempt to invoke the GetOriginalValue method on an object when the concurrency control is not set to changed and the MaintainOriginalValues property is not set to true, then a new NotSupportedException will be thrown.

When you are using the changed concurrency control, you don't have to set the MaintainOriginalValues property to true. The changed concurrency control is working by storing the original values, so they will be available without this option.