Ticket Q251721
Visible to All Users

How do I create a readonly property?

created 15 years ago (modified 7 years ago)

Hi, I have an autoincrement column in my class and whenever I try and save the object, I get an 'Autoincrement' fields cannot be updated.
It is not a key so how can I set it to be readonlu.
The following code stops the error but the value of ID in a record I am selecting always shows 0. It should be showing 1833242

C#
private int _ID; [PersistentAlias("mID")] public int ID { get { return _ID; } set { SetPropertyValue("ID", ref _ID, value); } }

What am I doing wrong?

Comments (2)
DevExpress Support Team 15 years ago

    Hi Mike,
    Thanks for your question. I suggest that you map a private field to an auto-incremented column, and create a read-only non persistent property to retrieve a value. Please see the code below:

    C#
    [Persistent("mID")] private int _ID; [PersistentAlias("_ID")] public int ID { get { return (int)EvaluateAlias("ID"); } }

    I've created a sample project, which works fine for me. Please review it, and let me know whether this solution meets your requirements.
    Thanks,
    Uriah.

      Hi Uriah,
      The following code gives this error:
      {"Schema needs to be updated. Contact your system administrator. Sql text: Error 7200: AQE Error: State = S0000; NativeError = 2121; [iAnywhere Solutions][Advantage SQL Engine]Column not found: mID -- Location of error in the SQL statement is: 11 AdsCommand query execution failed."}

      C#
      private int _ID; [PersistentAlias("mID")] public int ID { get { return _ID; } set { SetPropertyValue("ID", ref _ID, value); } }

      The following code works for display, but if I edit a row and then try and save the changes I get the following error:{"Executing Sql 'update "TCard" set "ID"=:p0,"CODE"=:p1,"JOB_NO"=:p2,"FM_NO"=:p3,"NOTE"=:p4,"DETAILS"=:p5,"DATE"=:p6,"USER_ID"=:p7,"TYPE"=:p8,"CUST_CODE"=:p1,"CALL_NUM"=:p9,"REP_CODE"=:p1,"STATUS"=:p1,"CREATED_TS"=:p10,"UPDATED_TS"=:p11,"OptimisticLockField"=:p12 where (("ROWID" = :p13) and ("OptimisticLockField" = :p14))' with parameters '{2342088},{},{01000022},{MA FORM},{test for crm},{{\rtf1\deff0{\fonttbl{\f0 Times New Roman;}}{\colortbl\red0\gree…},{15/03/2010 00:00:00},{MIKE},{C},{32088},{15/03/2010 16:11:26},{16/03/2010 12:26:57},{9},{9FQVWL_ASaKYVBgAfMFykQ},{8}' exception 'Advantage.Data.Provider.AdsException: Error 7200: AQE Error: State = HY000; NativeError = 5066; [iAnywhere Solutions][Advantage SQL][ASA] Error 5066: The requested operation is not legal for the given field type. AutoIncrement fields are read only. AdsCommand query execution failed.\r\n at Advantage.Data.Provider.AdsCommand.ExecuteStatement(IntPtr& hCursor, String& strIndex)\r\n at Advantage.Data.Provider.AdsCommand.ExecuteNonQuery()\r\n at DevExpress.Xpo.DB.ConnectionProviderSql.InternalExecSql(IDbCommand command)\r\n at DevExpress.Xpo.DB.ConnectionProviderSql.ExecSql(Query query)'"}

      C#
      [Persistent("ID")] private int _ID; [PersistentAlias("_ID")] public int ID { get { return (int)EvaluateAlias("ID"); } }

      The field in the table is called ID and is an auto increment field type. I am using Advantage Database Server V9.
      Regards
      Mike

      Answers approved by DevExpress Support

      created 7 years ago

      We have added support for read-only database columns in XPO. If you would like to test this feature prior to the official 18.2 release, get the preview build in the How to map a property to a read-only database column ticket. Your feedback is welcome.

        Other Answers

        created 15 years ago

        Hi Mike,
        Sorry, I've missed this problem. It's caused by the fact that XPO includes all persistent properties into the update query. You can work around the problem by creating your own Session descendant, and overriding its GetPropertiesListForUpdateInsert method as shown below:

        C#
        protected override MemberInfoCollection GetPropertiesListForUpdateInsert(object theObject, bool isUpdate) { MemberInfoCollection propertiesForUpdateInsert = base.GetPropertiesListForUpdateInsert(theObject, isUpdate); for (int i = propertiesForUpdateInsert.Count - 1; i >= 0; i--) if (propertiesForUpdateInsert[i].FindAttributeInfo("ExcludeFromUpdate") != null) propertiesForUpdateInsert.RemoveAt(i); return propertiesForUpdateInsert; }

        This method checks whether the CustomAttribute attribute is applied to a property, and removes it from the update list.
        Attached is a sample project. Also, please track the Calculated persistent properties - Add the Fetch parameter to PersistentAlias suggestion.
        Thanks,
        Uriah.

          Comments (3)

            Hi Uriah,
            That works perfectly. Thank you.
            Regards
            Mike

            MB MB
            Mario Blatarić 7 years ago

              Hi,

              It has been 8 years, so I want to check if this is still the case.

              It seems it is because I am experiencing the same issue - insert clause contains read-only property.

              Since I am not comfortable writing Session descendant at current stage of application just to remove a property from insert query that never should have been there in the first place - I would like to ask if there is another way to accomplish this?

              I understand private persistent fields can be used to initialize values inside object itself and persisted to database, but that can be accomplished in other ways as well - for instance creating regular property and setting UI elements as read-only.

              However, putting such fields in update/insert excludes other important usage - having database generated property which we only want to show in application.
              Using private persistent field exposed through public read-only property seems like a perfect fit, but unusable because those fields ends up in update/insert query which then throws database errors.

              Regards,
              Mario

              DevExpress Support Team 7 years ago

                Hi Mario,

                I've created a separate ticket on your behalf (T569875: How to use map persistent properties to read-only columns). It has been placed in our processing queue and will be answered shortly.

                Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

                Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.