JSON serialization
When used Json.NET XData data objects are serialized and deserialized automatically.
There are some serialization specifics of data objects:
- By default Read only properties and Hidden properties are serialized and deserialized as well as writable properties, but have a some restrictions when copied to object to apply into database (see Apply method description below).
- Large objects) are serialized to null value by default. They are designed for lazy data loading. To serialize data with actual values one of LoadLob helper method overloads can be used.
- By default Links are serialized as limited representation of link source object. Only properties listed as LinkProperties are included in serialized object. Additionally an "linkPropertyName.Value" JSON property is serialized with the value of Link.Value property.
Default serialization rules can be overrided with ICollection<T> and T WithJsonSettings extension methods.
JsonSettings<T> has followed methods to specify serializing options:
- Hide - alow to specify properties to skip on serialization
- LoadLob - alow to specify large object properties to load data before serialize (LoadLob method alternative)
- LinkMode - alow to specify serialization rules for multiple (or all) link properties:
- Default - default rules will be applied (see above)
- Value - only value will be serialized
- Source - only source will be serialized
- DeleteFlag - allow to delete child entities in database using unmapped boolean property value in JSON serialized child object (see below). Used to deserialized (detached) objects only!
return dataScope.GetRepository<Some>().ToArray()
.WithJsonSettings(s => s.Hide(JsonHideFlags.Columns) //hide all columns
.Hide(x => x.SomeReadOnlyProperty) //hide SomeReadOnlyProperty
.LoadLob() //load all large data properties
.LinkMode(LinkMode.Default,
x => SomeLinkProperty, x => AnotherLinkProperty) //set default rules to 2 properties
.LinkMode(LinkMode.Value)); //set other link properties serialize Value property only
Warning
Deserialized objects are detached from repository and had limited ways of using!
- Deserialized object can be used as a filter to find data object in database (for example to delete) with Find method:
var found = dataScope.GetRepository<Some>().Find(detachedObj);
if(found == null) throw new DbConcurrencyException();
return found.SetDeleted(true).Submit();
- Deserialized object can be used as a source to copy some data to new object with Copy method:
return dataScope.GetRepository<Some>().New().Copy(detachedObj).Submit();
- Deserialized object can be used as to apply changes to database with Apply method:
dataScope.GetRepository<Some>().Apply(detachedObj).Submit();
Apply is a combination of Find and Copy methods with followed algorithm:
1) if detached object has all keys assigned, corresponded object will be searched in database using keys and correlation token (if described in mapping) values (*)
2) if no data found XDataConcurrencyException will be trowed (**)
3) when some key properties are not assigned new entity has been created
4) detached object's data will be copied to found (or new) object (***)
(*) Using of correlation token value with Find method can be escaped with optional ignoreConcurrency parameter. Same result can be reached with ApplyFlag.IgnoreConcurrency flag has been passed in Apply method call.
(**) ApplyFlag.AddWhenNotFound flag can be passed in Apply method call to add new entity when not found in database.
(***) Copy and Apply has parameter properties to specify witch property values will be copied. ApplyFlag.ExceptProperties flag can be used to SKIP listed properties on copy. ApplyFlag.CopyReadOnlyProperties flag can be used to allow copy Read only properties and Hidden properties disabled by default.
You can define child repositories and associate them using the property parameter of the GetChild method with an unmatched property with the type of the child repository (for one-to-one relationships) or with a typed array of the child repository (for one-to-many relationships) . These properties will be populated during data collection, and the values will be automatically serialized to JSON and deserialized from JSON to a detached object. These values can be used to cascade changes to the database. Inserting and updating child objects is supported without further action. But for deleting entities, it is required that the developer define a delete flag - it the unmapped property used as a flag to mark the child entity as removed. To specify which property will be used as the delete flag for the property associated with the child repository, the WithJsonSettings method is used with the DeleteFlag combination applied to the detached object.
// set delete flag to child repository entities to unmapped boolean property
dataScope.GetRepository<Some>()
.Do(x => x.Instance.GetChild<Child>(z => z.Childs),
x => detachedObj.WithJsonSettings(
z => z.DeleteFlag(y => y.Childs, y => y.Deleted)))
.Apply(detachedObj).Submit();
See Master-detail relations to get more information about linking objects with Master-detail relations.