Working with HighLow Keygen API
Telerik Data Access exposes API for generating unique values for a specified string. This is useful for the cases where you use a Guid primary key, but you still need to associate your persistent type with a unique value, so that it makes a more user readable URL. Such unique values can be obtained based on the HIGHLOW key generation algorithm. This functionality is exposed via an API and it allows you to obtain unique values (for non-primary key fields) for a specified string.
In this topic:
- Generating Unique Integer Values
- Adding voa_keygen Table
- Using the UniqueIdGenerator in Transactions
Generating Unique Integer Values
The OpenAccessContext exposes a method named GetUniqueId, which can be used to get a unique id for a placeholder string. Note that for a specified persistent type with the HIGHLOW key generator the primary key value is generated internally and has nothing to do with the 'GetUniqueId' API. The API can be looked upon as a way to generate unique values for a specified string. The specified string is stored in the voa_keygen table in lower case with a '#' at the start, e.g. '#forumkey'
In order to represent all information that is needed to request a unique id, you need to create a new UniqueIdGenerator instance.
Telerik.OpenAccess.UniqueIdGenerator idGenerator = new Telerik.OpenAccess.
UniqueIdGenerator("ForumKey");
Dim idGenerator As New Telerik.OpenAccess.UniqueIdGenerator("ForumKey")
The Name property specifies the sequence for which unique id values should be generated. Additionally, you could configure the GrabSize and the Seed. The GrabSize property controls the minimal number of new keys fetched in one server call. The Seed property specifies the starting value that will be used by the unique id generator. You could configure the GrabSize and the Seed using a context instance. Additionally, the Initialize method exposed by the UniqueIdGenerator class allows you to calculate the Seed and GrabSize by using a context instance.
The following example shows you how to return a unique id value for the specified UniqueIdGenerator instance.
using (FluentModel dbContext = new FluentModel())
{
UniqueIdGenerator idGenerator = new UniqueIdGenerator("ForumKey");
int id = dbContext.KeyGenerators.GetUniqueId(idGenerator);
ForumPost forumPost = new ForumPost();
forumPost.Name = "Roadmap";
forumPost.ForumKey = id;
dbContext.Add(forumPost);
dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
Dim idGenerator As New UniqueIdGenerator("ForumKey")
Dim id As Integer = dbContext.KeyGenerators.GetUniqueId(idGenerator)
Dim _forumPost As New ForumPost()
_forumPost.Name = "Roadmap"
_forumPost.ForumKey = id
dbContext.Add(_forumPost)
dbContext.SaveChanges()
End Using
The GetUniqueIds method allows you to get a collection of unique values. For example, the following call means that if the key generator has 500 keys then these are returned else the remaining keys are lost and fresh 500 keys are fetched and returned. This call guarantees that there are no holes in 500 fetched ids.
UniqueIdGenerator idGenerator = new UniqueIdGenerator("ForumKey");
IEnumerable<int> id = dbContext.KeyGenerators.GetUniqueIds(idGenerator, 500);
Dim idGenerator As New UniqueIdGenerator("ForumKey")
Dim id As IEnumerable(Of Integer) = dbContext.KeyGenerators.GetUniqueIds(idGenerator, 500)
Adding Voa_Keygen Table
Telerik Data Access has to know about the additional highlow key usage upfront to be able to create/update the schema with the respective voa_keygen table. A property on the container notifies the runtime that the key generator table is needed (even though there is no persistent type with the HIGHLOW key generator). So, in order to use the API, you must set the container.UniqueIdGenerator.CreateTable property to True.
dbContext.Metadata.UniqueIdGenerator.CreateTable = true;
dbContext.Metadata.UniqueIdGenerator.CreateTable = True
By default Telerik Data Access will use the name voa_keygen. And if the table already exists in the database (e.g. you have persistent types with HIGHLOW key generator), then Telerik Data Access will use this table. However, if you need to maintain a separate keygen table (different than the one used by the persistent types), then you can further configure the settings by using the container.UniqueIdGenerator.TableName property.
dbContext.Metadata.UniqueIdGenerator.TableName = "UniqueIdsTable";
dbContext.Metadata.UniqueIdGenerator.TableName = "UniqueIdsTable"
Now the schema script contains the table definition.
ISchemaHandler schemaHandler = dbContext.GetSchemaHandler();
string ddlScript = schemaHandler.CreateUpdateDDLScript(null);
Dim schemaHandler As ISchemaHandler = dbContext.GetSchemaHandler()
Dim ddlScript As String = schemaHandler.CreateUpdateDDLScript(Nothing)
Transactions
The GetUniqueId method gets keys in a separate transaction. So if you have the following code:
using (FluentModel dbContext = new FluentModel())
{
UniqueIdGenerator idGenerator = new UniqueIdGenerator("ForumKey");
int id = dbContext.KeyGenerators.GetUniqueId(idGenerator);
ForumPost forumPost = new ForumPost();
forumPost.Name = "Roadmap";
forumPost.ForumKey = id;
dbContext.Add(forumPost);
dbContext.ClearChanges();
}
Using dbContext As New FluentModel()
Dim idGenerator As New UniqueIdGenerator("ForumKey")
Dim id As Integer = dbContext.KeyGenerators.GetUniqueId(idGenerator)
Dim _forumPost As New ForumPost()
_forumPost.Name = "Roadmap"
_forumPost.ForumKey = id
dbContext.Add(_forumPost)
dbContext.ClearChanges()
End Using
The call to context.ClearChanges() will rollback the changes on the context. However, the GetUniqueId call has committed the grabbed keys in a separate transaction.