Readonly persisted discriminator column

Posts   
 
    
ChrisCY
User
Posts: 22
Joined: 20-Jun-2007
# Posted on: 21-Apr-2010 14:36:36   

Hi people!

I am currently investigating the 'Inheritance' capabilities of LLBLGen in order to use them in a new project. I am using v2.6 against SqlServer 2005 generating C# through the Adapter template (.NET 3.5).

I am currently using the TargetPerEntity method to map hierarchies which does not require a Discriminator column. I marked the Root entity as Abstract.

What I need is to declare a discriminator column at the Root Entity (even if it is not required by LLBLGen) with the following characteristics: 1. It corresponds to an actual column in the database and be persisted. This helps a lot with reporting 2. When I instantiate a subtype, the value of this column is set automatically 3. When my code manipulates entities of the Root type, it cannot change the value of the Discriminator column, the Property is Read-only

What I did so far was to create the column and mark it a readonly in the designer. For each Subtype, I created a partial class which overrides the OnInitialized method but I can't set the value of the discriminator property since it is readonly!

Do you have any thoughts on how to deal with this?

Thanking you in advance! Chris

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 21-Apr-2010 15:28:54   

Please try using the entityField's ForcedCurrentValueWrite() method to set the value, and don't forget to set the field's IsCahnged property to true to be persisted.

ChrisCY
User
Posts: 22
Joined: 20-Jun-2007
# Posted on: 21-Apr-2010 16:09:25   

Thank you for the reply Walaa!

I will try it and let you know.

Chris

ChrisCY
User
Posts: 22
Joined: 20-Jun-2007
# Posted on: 22-Apr-2010 11:19:35   

Well, it seems that this does not work, since a readonly field is never emited back to the database through the generated sql.

I took some ideas from this thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=14821 but I did not implement the solution proposed there.

I consider this functionality as part of the DAL thus I don't want to involve the BL in this. We are also using LLBLGenDataSource2 heavily thus I need this to be transparent there too!

What I did was something along the following lines:

    public partial class TypeASecurityEntity
    {
        private bool _allowSecurityTypeUpdate = false;

        protected override void OnInitialized()
        {
            base.OnInitialized();

            _allowSecurityTypeUpdate = true;
            this.SecurityType = "A";
            _allowSecurityTypeUpdate = false;
        }


        protected override bool OnValidateFieldValue(int fieldIndex, object value)
        {
            if (fieldIndex == (int)TypeASecurityFieldIndex.SecurityType)
            {
                if (_allowSecurityTypeUpdate && value.ToString().Equals("A"))
                {
                    return true;
                }

                return false;
                //throw new ORMFieldIsReadonlyException("You are not allowed to modify the 'SecurityType' field.");
            }

            return base.OnValidateFieldValue(fieldIndex, value);
        }
    }

where TypeASecurity is a Sub-Entity of SecurityEntity and the discriminator property is 'SecurityType'.

This seems to work since the value is set correctly when I create a new TypeASecurityEntity and when I set the value through code

TypeASecurityEntity typeA = new TypeASecurityEntity();
typeA..SecurityType = "C";

the new value is ignored by the framework.

I also considered throwing an Exception in case the value is set. The fact that the 'client' code behaves differently than expected is the only bad smell I get from this approach. But so far it serves the purpose.

Thanks again for directing me. Chris