Ticket Q368491
Visible to All Users
Duplicate

We have closed this ticket because another page addresses its subject:

How to map a property to a read-only database column

xpo and sql server identity fields

created 13 years ago

Hi,
I have a table in Sql Server with a Guid primary key, and another integer identity field which is auto generated and unique in the table. When creating its persistent class, xpo creates this identity field as a property like every other, but when i try to save this entity back, it tries to insert a value into the database. It includes this field in the insert statement that it creates. Ofcourse database wont let this because of the auto-generated identity field, throws an exception and therefore i'm unable to save this entity.
I tried making the property read-only, making the set part private, and making the whole property [NonPersistent], but when i do any of these then the property does not get filled with the value from the database when i retrieve the entity.
Whats the solution to this, how can i make this property get its value when retrieving the entity, and not crash while saving it back?

Show previous comments (2)
DevExpress Support Team 13 years ago

    Hi Emre,
    Calculated columns cannot be mapped to persistent object properties either. XPO provides an alternative solution: declare a read-only property decorated with the PersistentAlias attribute, and specify the required expression in the attribute constructor. Please refer to the PersistentAttribute Class documentation.
    Thanks,
    Michael.

      Hi

      to solve this Problem:
      - Create your own IgnoreInsertUpdateAttribute to mark your persistent properties, which should not be inserted or updated
      - Create your custom session class, that inherits from DevExpress.Xpo.Session and override the GetPropertiesListForUpdateInsert method.

      C#
      [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class IgnoreInsertUpdateAttribute : Attribute { } public class MySession : DevExpress.Xpo.Session { protected override DevExpress.Xpo.Metadata.Helpers.MemberInfoCollection GetPropertiesListForUpdateInsert(object theObject, bool isUpdate, bool addDelayedReference) { var result = base.GetPropertiesListForUpdateInsert(theObject, isUpdate, addDelayedReference); var membersToRemove = new List<XPMemberInfo>(); foreach (XPMemberInfo memberInfo in result) { if (memberInfo.HasAttribute(typeof(IgnoreInsertUpdateAttribute))) { membersToRemove.Add(memberInfo); } } foreach (XPMemberInfo memberInfo in membersToRemove) { result.Remove(memberInfo); } return result; } }
      C#
      public calss MyBusinessOBject { ... [Persistent("Nr")] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] <bold>[IgnoreInsertUpdate] </bold> private int __nr; [PersistentAlias("nr")] public int Nr { get { return this.__nr; } } ... }
      OG OG
      Oliver Gröger 7 years ago

        Is there anything new on this topic? If there is not, how can I ensure my own Session will be used by XAF?

        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 7 years ago (modified 7 years ago)

          While this scenario isn't currently supported by XPO out of the box, you can do either of the following.
          A. Remove the auto-increment type property from the persistent class definition or declare it as a primary key (instead of the Guid type property).
          B. Create a custom Session or UnitOfWork descendant and override the GetPropertiesListForUpdateInsert method to filter out read-only properties. Refer to the How to map a property to a calculated database column (implement a read-only persistent property) ticket and the code example provided by Marco G. in the current thread. To use a custom UnitOfWork in XAF, create a custom XPObjectSpaceProvider descendant and override the CreateUnitOfWork method.

            Comments (1)
            OG OG
            Oliver Gröger 7 years ago

              It's amazing that after 7 years (and an update after 5 years) this feature has not found it's way into the product especially the code for its implementation has been provided by the community :(

              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.