PropertyValueAttribute - A Setting for IDbDataParameter
Published:
We are very excited to announce the availability of the PropertyValueAttribute object. It enables you (as a user of the library) to set the property of the IDbDataParameter object before the actual execution against the database.
Implicit Mapping
RepoDB allows you to fluently map a property into its destination object from the database (i.e.: TableName, ViewName and ColumnName).
The main goal is to eliminate the decoration of the attributes on your entity model (and property) so it is decoupled from the ORM framework.
Therefore, you are not limited to this anymore.
[Map("[dbo].[Person]")]
public class Person
{
[Map("FName")]
public string FirstName { get; set; }
...
}
But instead, do this.
FluentMapper
.Entity<Person>()
.Table("[dbo].[Person]")
.Column(e => e.FirstName, "FName");
However, the support is limited only to the following objects.
- TableName/ViewName
- ColumnName
- DbType
- Identity/Primary
- ClassHandler/PropertyHandler
Explicit Attribute
Before the release of RepoDb v1.12.9, there is no way we can override the value being passed to the properties of the IDbDataParameter object (i.e.: Size, Precision and Scale) and even to the other parameter object properties (i.e.: SqlParameter, NpgsqlParameter, SqliteParameter, MySqlParameter, etc). In the recent release, we introduced various attributes that address this need.
Currently, the library is taking the settings value from the database and there is no explicit way to override that, except for TypeMap and Name mappings.
As a sample, the SizeAttribute object, which inherited the PropertyValueAttribute object, is used to explicitly set the value of the Size property of the IDbDataParameter object before the actual execution against the database.
See below the explicit declaration of this attribute.
public class Person
{
[Size(256)]
public string FirstName { get; set; }
...
}
And its equivalent implicit mapping.
FluentMapper
.Entity<Person>()
.PropertyValueAttributes(e => e.FirstName, new SizeAttribute(256));
We can as well map multiple attributes together (in one go).
FluentMapper
.Entity<Person>()
.PropertyValueAttributes(e => e.FirstName, new PropertyValueAttribute[]
{
new NameAttribute("FName"),
new SizeAttribute(256),
new DbTypeAttribute(DbType.NVarChar)
});
The other attributes that were introduced are the following:
PropertyValueAttribute
What makes it more exciting is the dynamic capability of the PropertyValueAttribute object. This object is designed to be more extensible to cater to all the scenarios pertaining to the setting of the properties of the IDbDataParameter object.
The constructor has 3 arguments, all of which are required to be called from the derived classes.
- ParameterType - the type of the parameter object.
- PropertyName - the name of the target property from the parameter object.
- Value - the actual value to be set.
Below is a sample customized class you can create to set the NpgsqlDbType property of the NpgsqlParameter.
public class MyCustomizedNpgsqlDbTypeAttribute : PropertyValueAttribute
{
public MyCustomizedNpgsqlDbTypeAttribute(NpgsqlDbType type)
: base(typeof(NpgsqlParameter), nameof(NpgsqlParameter.NpgsqlDbType), type)
{ }
}
And use it as your decorative attribute.
public class Person
{
[MyCustomizedNpgsqlDbType(NpgsqlDbType.Text)]
public string FirstName { get; set; }
...
}
Or even fluently map it into your entity.
FluentMapper
.Entity<Person>()
.PropertyValueAttributes(e => e.FirstName, new MyCustomizedNpgsqlDbTypeAttribute(256));
Once mapped, all the operations will apply the settings to the corresponding property of the IDbDataParameter object (for the targeted entity model property). The settings are also being applied even to the dynamic queries (like below).
var people = connection.ExecuteQuery<Person>("[Person]", new { FirstName = "Somebody" });
Other Data Providers
The support for the other data providers has also been introduced. Below are the pre-created attribute objects.
- CompareInfo
- ForceColumnEncryption
- LocaleId
- Offset
- SqlDbType
- TypeName
- UdtTypeName
- XmlSchemaCollectionDatabase
- XmlSchemaCollectionName
- XmlSchemaCollectionOwningSchema
It is quite simple, yet powerful. We find this capability very useful for those of you who are working on advanced cases in which the settings are impossible to acquire within an existing operation.
For any issues found in relation to this capability, please report it directly to our Github page.
