News, examples, tips, ideas and plans.
Thoughts around ORM, .NET and SQL databases.

Friday, October 06, 2017

DataObjects.Net 5.0.16 Beta 1

We've released a new version recently. Here are the changes we have made:

[main] Added constraint option allowing to skip the constraint if the field isn't changed
[main] DifferentialTuple.Merge() operation no longer causes StackOverflow exception
[main] Fixed certain cases of foreign key absence for reference fields of structures
[main] Fixed translation of enum value as default field value
[sqlserver] Fixed extraction of information about indexes from database

As usual you can download it from our official website or install it from Nuget library

Complete changes description is below.

New PropertyValidator option

We have added a new property called ValidateOnlyIfModified for the field constraints. The property as you have probably guessed allows to skip certain constraints on validation if field value wasn't changed. For example,

  [HierarchyRoot]
  public class User : Entity
  {
    [Field, Key]
    public int Id { get; private set; }

    [Field(Length = 70)]

    // this constraint will validate field value
    // even if it is still
    [NotNullOrEmptyConstraint]
    public string FirstName { get; set; }

    [Field(Length = 70)]
    // this constraint will validate field value
    // only the value is changed
    [NotNullOrEmptyConstraint(ValidateOnlyIfModified = true)]
    public string LastName { get; set; }

  
    [Field(Length = 70, Nullable = true)]
    public string HiddenComment { get; set;}
  }

Now lets see how it works. Say, we want to add some comment to a user so we query the User entity and edit the HiddenComment field, the field without any validators, and don't change the rest of the fields like that:

  using (var session = domain.OpenSession())
  using (var tx = session.OpenTransaction()) {
    var johnUser = session.Query.All<User>()
      .First(u => u.FirstName=="John");

    johnUser.HiddenComment = "He is the best";

    // commit leads to validation
    tx.Complete();
  }

In this case, the constraint of the FirstName field will be triggered despite the field hasn't been changed. It is an example of constraints' regular behavior. More interestingly, the constraint of the LastName field will be skipped thanks to the new option.

Another case. We change the LastName field.

  using (var session = domain.OpenSession())
  using (var tx = session.OpenTransaction()) {
    var johnUser = session.Query.All<User>()
      .First(u => u.FirstName=="John");

    johnUser.LastName = "Brown";

    // commit leads to validation
    tx.Complete();
  }

Here, both of the constraints will cause validation of their fields - the first constraint will be triggered because it has to do it every time and the second one - because the field value has been modified.

Need to say, an attempt to change the field value is more important than an actual value which was set for the field. Check the example below

  using (var session = domain.OpenSession())
  using (var tx = session.OpenTransaction()) {
    var johnUser = session.Query.All<User>()
      .First(u => u.FirstName=="John" && u.LastName=="Brown");

    johnUser.LastName = "Brown";

    // commit leads to validation
    tx.Complete();
  }

The LastName field value will be validated despite the fact that the new value is actually the same as previous one. It happens because an entity registers for validation on set field value attempt and you should take this particularity into account.

Summing up all of the above, the new option will be helpful for those who for some reason don't want to validate untouched fields. Another possible case is when you are import some rows to DataObjects.net database and you are not completely sure the data is valid, with help of this option you will softly migrate data to valid state.

StackOverflowException on persist operation

Some of our customers faced with the exception, trying to save changes to storage. The error showed up on DifferentialTuple.Merge() operation. So if you have similar symptoms this may be your case. From this version the problem is fixed.

Foreign key absence for reference fields of structures

In cases like below

  [HierarchyRoot]
  public class InvoiceItem : Entity
  {
    [Field]
    public long Id { get; private set; }

    [Field]
    public Product Product { get; set; }

    [Field]
    // this field is important
    public ExtendedQuantity Quantity { get; set; }
  }

  [HierarchyRoot]
  public class Measure : Entity
  {
    [Field]
    public int Id { get; private set; }

    [Field]
    public string Name { get; set; }
  }

  public class ExtendedQuantity : Quantity
  {
    //some other fields
  }

  public class Quantity : Structure
  {
    [Field]
    public double Vaule { get; set; }

    [Field]
    public Measure Measure { get; set; }
  }

the association between the InvoiceItem type and Measure type used to be skipped and it led to absence of foreign key in database. Such behavior was incorrect so we've fixed it and since this version such foreign keys will be built correctly.

Enum field default value translation

There were cases when FieldAttrubute.DefaultValue for inherited fields of enum type translated incorrectly. For example:

  public enum ProductStage
  {
    //Some stages
  }

  [HierarchyRoot]
  public class Product : Entity
  {
    [Key, Field]
    public long Id { get; private set; }
      
    [Field(DefaultValue = OneTwo.One)]
    public ProductStage Stage { get; set; }
  }

  public class FinalProduct : Product
  {
  }


There is no longer a problem with default value translation.

Index related information extraction for MS SQL Server


There was a possibility of an error on schema extraction as DataObjects.Net tried to extract indexes which are not supported. The problem could show up in SQL Server beginning from 2014 version. We forced unsupported indexes to be skipped on extraction. If you have some unsupported indexes e.g. ColumnsStore indexes, they will be skipped so you should control them by yourself.


No comments:

Post a Comment