Page 1 of 1

request: automatic string length validation

Posted: Thu 15 Dec 2011 22:55
by mindplay
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...

Posted: Tue 20 Dec 2011 11:18
by Shalex
We will implement the synchronization for the Validate Max Length property after setting Length when using Model First approach. We will post here when this functionality is available.

Posted: Tue 20 Dec 2011 21:49
by mindplay
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:

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;
      }
    }
  }
It ties into the class generation loop like so:

Code: Select all

    foreach (HibernateClass cls in _namespace) {
      ConfigureMappings(cls); // add the call here...
      if (FilePerClass) {
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.

Posted: Fri 23 Dec 2011 11:10
by Shalex
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 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

Posted: Thu 12 Jan 2012 16:45
by Shalex
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 .

Posted: Mon 16 Jan 2012 21:27
by mindplay
Nice! Got rid of a bunch of "convention hacks" in my template :-)

One "hack" that remains in my template is this:

Code: Select all

      if (type == "bool") {
        property.Nullable = false;
        property.ValidateRequired = false;
      }
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>)