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?
We have closed this ticket because another page addresses its subject:
How to map a property to a read-only database columnxpo and sql server identity fields
Answers approved by DevExpress Support
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
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.
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 :(
Hi Emre,
I am afraid this scenario is not supported. To avoid the error, remove the auto-increment type property from the persistent class definition or declare it as a primary key (instead of the Guid type property).
Thanks,
Michael.
Hi,
Thanks for the prompt reply. Although i'm surprised such a common scenario is not supported, I have a further question. How about computed columns? Are these treated the same way?
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.
[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; } }
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; } } ... }
Is there anything new on this topic? If there is not, how can I ensure my own Session will be used by XAF?