DO 5.0.20

Same as NullableOnUpgrade

With [Recycled] field every perform would execute (ADD/DROP COLUMN)

It is not needed, because on first perform upgraders was executed and field removed from DB

Next performs:

  • can not doing useful things, because column data is empty
  • should not use this column


using System;
using Xtensive.Orm;
using Xtensive.Orm.Configuration;
using Xtensive.Orm.Upgrade;

class Program
    static void Main(string[] args)
        var dc = new DomainConfiguration("sqlserver://localhost/DO40-Tests");

        // First run
        //dc.UpgradeMode = DomainUpgradeMode.Recreate;
        dc.UpgradeMode = DomainUpgradeMode.Perform;


        using (var d = Domain.Build(dc))

public class Table : Entity
    public Table(Guid id)
        : base(id)

    [Field, Key]
    public Guid Id { get; set; }

    public string Field { get; set; }

asked Feb 20 '20 at 02:43

Gushchin%20Anton's gravatar image

Gushchin Anton

One Answer:

Hello Anton,

Sorry but we can't do that because otherwise we would intentionally break our mechanisms. And it is not good for product's stability and reliability.

Let's dive into internal processes of Domain building. Domain model building has following steps (if we simplify it):

  1. get all registered types
  2. build definitions (TypeDefs, FieldDefs, IndexDefs, etc.)
  3. pass raw definitions to IModule.OnDefinitionsBuilt(BuildingContext, DomainModelDef) method for customer to make changes if he will
  4. validate result definitions
  5. build infos (DomainModel with TypeInfos, FieldInfos, IndexInfos, etc.). Any modifications of DomainModel after it is built are forbidden, the model becomes locked.

These steps are isolated have no idea about current database structure, more then that, by default they execute in parallel with database schema extraction.

Each TypeInfo and FieldInfo must be represented in database as table and column respectively. We should guarantee that, this is vital for stable work.

You also probably know that in Perform/PerformSafely upgrade modes we build two Domain models - one for upgrade (on Upgrading stage, you work with this model in UpgradeHandler.OnUpgrade() method) and another one as final model (included to the Domain instance you receive). And [Recycled] attribute on a field or a type basically says to include the field or the type into upgrading model and avoid including them to the final model. So the field or the type should be represented in database on Upgrading stage and should not when you receive Domain instance.

Now back to your suggestion, since we have no chance to avoid building FieldInfo for recycled field in upgrading model the only way is to not build assigned column. If we did that we would have the recycled field as FieldInfo but no column for it in database. We can't allow such desynchronized states of database and domain model.

Moreover, we don't know exact consequences of states being desynchronized but obviously nothing good will happen. Now, if a field is not represented in Domain model (and in database) you get expected and predictable exception telling you about absence, execution won't go further and that's great. With desychronized states this protection wouldn't work, a query translation, for instance would execute further and only God knows what exception you would have as result. This is unpredictable and really bad for you and for other customers.

answered Feb 20 '20 at 06:46

Alexey%20Kulakov's gravatar image

Alexey Kulakov

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview


Once you sign in you will be able to subscribe for any updates here



Asked: Feb 20 '20 at 02:43

Seen: 1,603 times

Last updated: Feb 20 '20 at 06:46

powered by OSQA