How about adding an option to the default NH template, to automatically add string-length validation for string properties?
I dislike the idea of having to specify the string length twice for every property - first for the field itself, then again for validation. Having to maintain the same value twice, makes it easy to make a mistake...
request: automatic string length validation
What I'm after, personally, is validation by convention - I don't want two copies of the same value, or worse, two different representations of the same value - it's an invitation to create buggy mappings.
For example, you can create a property with Nullable=True and Column.NotNull=True - which doesn't make any sense... ValidateRequired is also redundant in most cases, so you're maintaining this setting in triplicate. (at least, Nullable could drive the default for the other two settings.)
You can also create a property with Column.Length=50 and ValidateMaxLength=100 - which does not make sense... again, Column.Length could easily drive the default.
I managed to implement this myself:
It ties into the class generation loop like so:
Anyone wants to use this, be warned: this script is destructive - apparently, the changes made to these objects will persist in the IDE! In other words, you can no longer manually control ValidateMaxLength, ValidateRequired or Column.NotNull. You've been warned!
Note to the programmers: please consider passing clones of the model objects to the template, so that templates can't destroy the model project.
For example, you can create a property with Nullable=True and Column.NotNull=True - which doesn't make any sense... ValidateRequired is also redundant in most cases, so you're maintaining this setting in triplicate. (at least, Nullable could drive the default for the other two settings.)
You can also create a property with Column.Length=50 and ValidateMaxLength=100 - which does not make sense... again, Column.Length could easily drive the default.
I managed to implement this myself:
Code: Select all
//////////////////////////////
//
// Apply mapping conventions
//
//////////////////////////////
private void ConfigureMappings(HibernateClass cls) {
foreach (HibernateProperty property in cls.Properties) {
var type = codeProvider.GetNullableType(property.Nullable, property.Type);
if (type == "string") {
if (property.Column.Length > 0) {
property.ValidateMaxLength = property.Column.Length;
} else {
property.ValidateMaxLength = null;
}
property.ValidateRequired = !property.Nullable;
property.Column.NotNull = !property.Nullable;
}
}
}
Code: Select all
foreach (HibernateClass cls in _namespace) {
ConfigureMappings(cls); // add the call here...
if (FilePerClass) {
Note to the programmers: please consider passing clones of the model objects to the template, so that templates can't destroy the model project.
The General tab in the Properties window defines behaviour of a model class property.
The Column tab is taken into account in the following cases:
- generating DDL of the column when using Generate Database Script From Model
- comparing storage part of the model and database itself in Update Model From Database / Update Database From Model wizards
You may have a non-nullable class property for a nullable column in the database.
So, "Nullable" and "Not Null" are two conceptually different settings.
Behaviour will be changed starting from the next build:
The Column tab is taken into account in the following cases:
- generating DDL of the column when using Generate Database Script From Model
- comparing storage part of the model and database itself in Update Model From Database / Update Database From Model wizards
You may have a non-nullable class property for a nullable column in the database.
So, "Nullable" and "Not Null" are two conceptually different settings.
Behaviour will be changed starting from the next build:
- the Validate Max Length attribute will be synchronized with the Length attribute of Column by default
- the Validate Required attribute will be synchronized with the Nullable attribute of Property by default
- implicit NOT NULL column's attribute in SQL script will be determined by the Nullable attribute of Property
New build of Entity Developer 4.2.110 is available for download now!
It can be downloaded from http://www.devart.com/entitydeveloper/download.html (trial version) or from Registered Users' Area (for users with valid subscription only).
For more information, please refer to http://www.devart.com/forums/viewtopic.php?t=23135 .
It can be downloaded from http://www.devart.com/entitydeveloper/download.html (trial version) or from Registered Users' Area (for users with valid subscription only).
For more information, please refer to http://www.devart.com/forums/viewtopic.php?t=23135 .
Nice! Got rid of a bunch of "convention hacks" in my template
One "hack" that remains in my template is this:
Booleans are simple, but the built-in defaults don't make much sense.
A Boolean should be Nullable=false by default, because, well, otherwise it's not a Boolean - "tristate" (0/1/NULL) columns are much less common than binary (0/1) columns.
Since ValidateRequired is now automatically configured when setting the Nullable property, this need to be False, as there is no way to check a truly binary (not nullable) Boolean value for "presence". (it can't be NULL, or it wouldn't be Boolean - it would be Nullable<Boolean>)
One "hack" that remains in my template is this:
Code: Select all
if (type == "bool") {
property.Nullable = false;
property.ValidateRequired = false;
}
A Boolean should be Nullable=false by default, because, well, otherwise it's not a Boolean - "tristate" (0/1/NULL) columns are much less common than binary (0/1) columns.
Since ValidateRequired is now automatically configured when setting the Nullable property, this need to be False, as there is no way to check a truly binary (not nullable) Boolean value for "presence". (it can't be NULL, or it wouldn't be Boolean - it would be Nullable<Boolean>)