Database Naming Rules
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
Sometimes, when you use default mapping, the generated database artifact names are not always what you would expect. For example, you may have a class named "ShipAddress" with a field named "spAdr" and the generated database column will be "sp_adr". Telerik Data Access allows you to specify various naming rules and settings that will be applied on the generated relational items (tables and columns) during Code-Only Scenario. For example, it is possible to instruct Telerik Data Access to use the property name as it is for the column name. The same is valid for the default table name, i.e. it could be based on the class name. The main benefit is that you have control over the generated column names and you don't have to manually change the column name(s) for each field/property. You will always get similar column names based on what you see in the conceptual (fluent) model.
The following example shows a sample default mapping configuration for the Product class.
MappingConfiguration<Product> productConfiguration = new MappingConfiguration<Product>();
productConfiguration.MapType();
productConfiguration.HasProperty( x => x.ID ).IsIdentity( KeyGenerator.Autoinc );
Dim productConfiguration As MappingConfiguration(Of Product) = New MappingConfiguration(Of Product)()
productConfiguration.MapType()
productConfiguration.HasProperty(Function(x) x.ID).IsIdentity(KeyGenerator.Autoinc)
productConfiguration.FieldNamingRules.AddPrefix = "_"
If you execute the DDL script for the previous example a new table named "product" with columns i_d and product_name will be generated in the database. This is the default behavior of Telerik Data Access.
How the Default Algorithm is Working
The existing name generation algorithm performs the following actions on the input string (field or property name):
- Remove leading underscores ( _ ).
- Replace '/' with the 'wordBreak' value ( '_' by default).
- Remove all occurences of '$' and '.' (dot).
- Separate CamelCased names with camel_case (using the wordbreak as a separator).
- Check if generated name is reserved keyword and replace it with an hard coded alternative (e.g. name -> nme).
- If after doing the above the length is greater than maxLength then all wovels are stripped out starting from the 2nd character
- If length is still greater than it is trimmed at maxLength.
Controlling Table and Column Names
This section demonstrates:
- How to set the table/column names to match exactly the class/property names. Read more
- How to set table names to match exactly the class names and the column names to match exactly field names. Read more
Telerik Data Access exposes various settings through the MetaNameGenerator class that can be used to obtain the desired behavior. What you need to do is to override the CreateModel method in the FluentModelMetadataSource class and obtain the MetaNameGenerator instance.
protected override MetadataContainer CreateModel()
{
MetadataContainer metadataContainer = base.CreateModel();
MetaNameGenerator metaNameGenerator = metadataContainer.NameGenerator;
return metadataContainer;
}
Protected Overrides Function CreateModel() As MetadataContainer
Dim _metadataContainer As MetadataContainer = MyBase.CreateModel()
Dim _metaNameGenerator As MetaNameGenerator = _metadataContainer.NameGenerator
Return _metadataContainer
End Function
Table/Column Names Matching Exactly Class/Property Names
The following configuration allows you to generate script with table/column names matching exactly the class/property names in the Fluent Model. Note that regardless of the selected name processing options, all invalid symbols in the property/field name will be removed so that you don't experience errors while running the generated script. The result will be a table named "Product" with columns - "ID" and "ProductName".
protected override MetadataContainer CreateModel()
{
MetadataContainer metadataContainer = base.CreateModel();
MetaNameGenerator metaNameGenerator = metadataContainer.NameGenerator;
metaNameGenerator.RemoveCamelCase = false;
metaNameGenerator.ResolveReservedWords = false;
metaNameGenerator.SourceStrategy = NamingSourceStrategy.Property;
return metadataContainer;
}
Protected Overrides Function CreateModel() As MetadataContainer
Dim _metadataContainer As MetadataContainer = MyBase.CreateModel()
Dim _metaNameGenerator As MetaNameGenerator = _metadataContainer.NameGenerator
_metaNameGenerator.RemoveCamelCase = False
_metaNameGenerator.ResolveReservedWords = False
_metaNameGenerator.SourceStrategy = NamingSourceStrategy.Property
Return _metadataContainer
End Function
Table Names Matching Class Names and Column Names Matching Field Names
The following configuration allows you to generate script with table names matching exactly the class names in the Fluent Model, and column names matching the field names. Note that regardless of the selected name processing options, all invalid symbols in the property/field name will be removed so that you don't experience errors while running the generated script. The result will be a table named "Product" with columns - "iD" and "productName".
protected override MetadataContainer CreateModel()
{
MetadataContainer metadataContainer = base.CreateModel();
MetaNameGenerator metaNameGenerator = metadataContainer.NameGenerator;
metaNameGenerator.RemoveCamelCase = false;
metaNameGenerator.ResolveReservedWords = false;
metaNameGenerator.SourceStrategy = NamingSourceStrategy.Field;
return metadataContainer;
}
Protected Overrides Function CreateModel() As MetadataContainer
Dim _metadataContainer As MetadataContainer = MyBase.CreateModel()
Dim _metaNameGenerator As MetaNameGenerator = _metadataContainer.NameGenerator
_metaNameGenerator.RemoveCamelCase = False
_metaNameGenerator.ResolveReservedWords = False
_metaNameGenerator.SourceStrategy = NamingSourceStrategy.Field
Return _metadataContainer
End Function
Product Class
public class Product
{
private int iD;
public int ID
{
get
{
return iD;
}
set
{
iD = value;
}
}
private string productName;
public string ProductName
{
get
{
return productName;
}
set
{
productName = value;
}
}
}
Public Class Product
Private _iD As Integer
Public Property ID() As Integer
Get
Return _iD
End Get
Set(ByVal value As Integer)
_iD = value
End Set
End Property
Private _productName As String
Public Property ProductName() As String
Get
Return _productName
End Get
Set(ByVal value As String)
_productName = value
End Set
End Property
End Class