Data Synchronization
There are cases where you might want to update columns in the database but to leave the auto-calculated fields unchanged. In Telerik Data Access auto-calculated fields are version information and auto-set DateTime columns. Currently, Telerik Data Access allows a DateTime field to be automatically calculated when a CUD operation is executed. Such configuration is considered advanced and it is only possible with Fluent Mapping API. In cases where you want only to synchronize your data (e.g. when the same records are presented in two databases), you might want to set an explicit value to that DateTime field.
For such scenarios, Telerik Data Access includes a special mode which controls the behavior of the OpenAccessContext class instances during Insert and Update operations. This mode can be enabled via the EnableDataSynchronization property. This property is accessible through the OpenAccessContextOptions object that is exposed by the OpenAccessContext.
using (FluentModel dbContext = new FluentModel())
{
dbContext.ContextOptions.EnableDataSynchronization = true;
}
Using dbContext As New FluentModel()
dbContext.ContextOptions.EnableDataSynchronization = True
End Using
When the context is in a synchronization mode, any insert or update operations will not affect the auto-set DateTime columns configured with Fluent Mapping API. Another field that is also affected by this behavior is the version field when you use version as a concurrency control mechanism. The version number is incremented on every update. When EnableDataSynchronization is set to True, the version field is not changed on update operations and it is not set at all on insert operations. That’s why when you insert records in synchronization mode, you have to manually set a value to the version fields; otherwise, an exception will be thrown during SaveChanges.The EnableDataSynchronization is not a one-time setting. It can be switched on and off during the lifetime of the context.
Suppose, you have the following table on the server.
The DateTime column will be used for concurrency checks. You have a model including the Suppliers table. The Concurrency Mode for the Supplier entity is set to Timestamp and the Concurrency Member is set to the ModifiedDate column:
-
Add a field and a property in your persistent class for the DateTime column:
The type of the field and the property should be DateTime.
public partial class Supplier { //The code for the rest of the fields and properties private DateTime _modifiedDate; public virtual DateTime ModifiedDate { get { return this._modifiedDate; } set { this._modifiedDate = value; } } }
Public Partial Class Supplier ' The code for the rest of the fields and properties Private _modifiedDate As DateTime Public Overridable Property ModifiedDate As DateTime Get Return Me._modifiedDate End Get Set(ByVal value As DateTime) Me._modifiedDate = value End Set End Property End Class
-
In the metadatasource class of your model, set the concurrency control strategy of the Product class to Timestamp:
configuration.MapType(x => new { }). WithConcurencyControl(OptimisticConcurrencyControlStrategy.Timestamp). ToTable("Suppliers");
configuration.MapType(Function(x) New With {x}). WithConcurencyControl(OptimisticConcurrencyControlStrategy.Timestamp). ToTable("Supplier")
-
Add a new property configuration for the ModifiedDate column. Make sure to set it as version through the IsVersion method:
configuration.HasProperty(x => x.Timestamp).HasFieldName("_modifiedDate"). IsVersion().WithDataAccessKind(DataAccessKind.ReadWrite). ToColumn("ModifiedDate").IsNotNullable().HasColumnType("datetime"). HasPrecision(0).HasScale(0);
configuration.HasProperty(x => x.Timestamp).HasFieldName("_modifiedDate"). IsVersion().WithDataAccessKind(DataAccessKind.ReadWrite). ToColumn("ModifiedDate").IsNotNullable().HasColumnType("datetime"). HasPrecision(0).HasScale(0)
Each time a record is updated/inserted, the datetime column will be updated automatically by Telerik Data Access. However, you could prevent this by setting the EnableDataSynchronization property to True. Here is an example:
using (FluentModel dbContext = new FluentModel())
{
Supplier firstSupplier = dbContext.Suppliers.FirstOrDefault();
firstSupplier.Name = "John";
// The ModifiedDate column will be automatically updated by Telerik Data Access.
dbContext.SaveChanges();
dbContext.ContextOptions.EnableDataSynchronization = true;
firstSupplier.Name = "Ivan";
// This time the ModifiedDate column won't be updated.
dbContext.SaveChanges();
// The EnableDataSynchronization setting is not a one-time only setting.
dbContext.ContextOptions.EnableDataSynchronization = false;
dbContext.Name = "Josh";
dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
Dim firstSupplier As Supplier = dbContext.Suppliers.FirstOrDefault()
firstSupplier.Name = "John"
' The ModifiedDate column will be automatically updated by Telerik Data Access.
dbContext.SaveChanges()
dbContext.ContextOptions.EnableDataSynchronization = True
firstSupplier.Name = "Ivan"
' This time the ModifiedDate column won't be updated.
dbContext.SaveChanges()
' The EnableDataSynchronization setting is not a one-time only setting.
dbContext.ContextOptions.EnableDataSynchronization = False
dbContext.Name = "Josh"
dbContext.SaveChanges()
End Using
Limitations
- It is not possible to insert explicit values in a SQL Server timestamp column.
- It is not possible to update a record without updating the value in a Timestamp column. This means that, in the cases where you have configured a backend-specific concurrency control (e.g. Timestamp), Telerik Data Access won’t be able to keep the original value after data synchronization.