/// <summary> /// Construct the extension /// </summary> public IEnumerable <Extension> Construct(IIdentifiedEntity modelObject) { if (modelObject is Person person && person.DateOfBirthPrecision > DatePrecision.Day) { yield return(new Extension(this.Uri.ToString(), DataTypeConverter.ToFhirDateTime(person.DateOfBirth))); } }
/// <summary> /// Construct the extension /// </summary> public IEnumerable <Extension> Construct(IIdentifiedEntity modelObject) { if (modelObject is SanteDB.Core.Model.Roles.Patient patient && patient.ReligiousAffiliationKey.HasValue) { yield return(new Extension(this.Uri.ToString(), DataTypeConverter.ToFhirCodeableConcept(patient.ReligiousAffiliationKey))); } }
/// <summary> /// Ensure the specified object exists /// </summary> public static TModel EnsureExists <TModel>(this TModel me, LocalDataContext context) where TModel : IIdentifiedEntity { // Me var vMe = me as IVersionedEntity; // We have to find it var idpInstance = LocalPersistenceService.GetPersister(me.GetType()); var existing = me.TryGetExisting(context); // Existing exists? if (existing == null && !m_readonlyTypes.Contains(typeof(TModel))) { IIdentifiedEntity inserted = ((TModel)idpInstance.Insert(context, me)) as IIdentifiedEntity; me.Key = inserted.Key; if (vMe != null) { vMe.VersionKey = (inserted as IVersionedEntity).VersionKey; } existing = inserted; } else if (existing == null) { throw new KeyNotFoundException($"Object {me} not found in database and is restricted for creation"); } return(existing == null ? me : (TModel)existing); }
/// <summary> /// Try get by classifier /// </summary> public static IIdentifiedEntity TryGetExisting(this IIdentifiedEntity me, ModelDataContext context, IPrincipal principal) { // Is there a classifier? var idpType = typeof(IDataPersistenceService <>).MakeGenericType(me.GetType()); var idpInstance = ApplicationContext.Current.GetService(idpType); IIdentifiedEntity existing = null; // Is the key not null? if (me.Key != Guid.Empty && me.Key != null) { // We have to find it var getMethod = idpInstance.GetType().GetRuntimeMethods().SingleOrDefault(o => o.Name == "Get" && o.GetParameters().Length == 3 && o.GetParameters()[0].ParameterType == typeof(ModelDataContext)); if (getMethod == null) { return(null); } existing = getMethod.Invoke(idpInstance, new object[] { context, me.Key, principal }) as IIdentifiedEntity; } var classAtt = me.GetType().GetCustomAttribute <KeyLookupAttribute>(); if (classAtt != null) { object classifierValue = me; // me.GetType().GetProperty(classAtt.ClassifierProperty).GetValue(me); // Follow the classifier Type predicateType = typeof(Func <,>).MakeGenericType(me.GetType(), typeof(bool)); ParameterExpression parameterExpr = Expression.Parameter(me.GetType(), "o"); Expression accessExpr = parameterExpr; while (classAtt != null) { var property = accessExpr.Type.GetRuntimeProperty(classAtt.UniqueProperty); accessExpr = Expression.MakeMemberAccess(accessExpr, property); classifierValue = property.GetValue(classifierValue); classAtt = accessExpr.Type.GetCustomAttribute <KeyLookupAttribute>(); } // public abstract IQueryable<TData> Query(ModelDataContext context, Expression<Func<TData, bool>> query, IPrincipal principal); var queryMethod = idpInstance.GetType().GetRuntimeMethods().SingleOrDefault(o => o.Name == "Query" && o.GetParameters().Length == 3 && o.GetParameters()[0].ParameterType == typeof(ModelDataContext)); var builderMethod = typeof(Expression).GetGenericMethod(nameof(Expression.Lambda), new Type[] { predicateType }, new Type[] { typeof(Expression), typeof(ParameterExpression[]) }); var expression = builderMethod.Invoke(null, new object[] { Expression.MakeBinary(ExpressionType.Equal, accessExpr, Expression.Convert(Expression.Constant(classifierValue), accessExpr.Type)), new ParameterExpression[] { parameterExpr } }) as Expression; if (queryMethod == null) { return(null); } var iq = queryMethod.Invoke(idpInstance, new object[] { context, expression, principal }) as IQueryable; foreach (var i in iq) { existing = i as IIdentifiedEntity; me.Key = existing.Key; if (me is IVersionedEntity) { (me as IVersionedEntity).VersionKey = (existing as IVersionedEntity)?.VersionKey ?? Guid.Empty; } } } return(existing); }
public static void SetLoaded(this IIdentifiedEntity me, string propertyName) { var loadCheck = new PropertyLoadCheck(propertyName); if (!me.GetAnnotations <PropertyLoadCheck>().Contains(loadCheck)) { me.AddAnnotation(loadCheck); } }
/// <summary> /// Try get by classifier /// </summary> public static bool CheckExists(this IIdentifiedEntity me, DataContext context) { // Is there a classifier? var serviceInstance = ApplicationServiceContext.Current.GetService <AdoPersistenceService>(); var idpInstance = serviceInstance.GetPersister(me.GetType()) as IAdoPersistenceService; if (me.Key.HasValue && me.Key != Guid.Empty) { return(idpInstance.Exists(context, me.Key.GetValueOrDefault())); } else { return(false); } }
/// <summary> /// Construct the extension /// </summary> public IEnumerable <Extension> Construct(IIdentifiedEntity modelObject) { if (modelObject is SanteDB.Core.Model.Roles.Patient patient) { // Birthplace? var birthPlaceRelationship = patient.LoadCollection(o => o.Relationships).FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Birthplace); if (birthPlaceRelationship != null) { var address = DataTypeConverter.ToFhirAddress(birthPlaceRelationship.LoadProperty(o => o.TargetEntity).LoadCollection(o => o.Addresses)?.FirstOrDefault()); var test = birthPlaceRelationship.TargetEntity.LoadCollection(o => o.Names); address.Text = birthPlaceRelationship.TargetEntity.LoadCollection(o => o.Names)?.FirstOrDefault(c => c.NameUseKey == NameUseKeys.Search)?.ToDisplay(); yield return(new Extension(this.Uri.ToString(), address)); } } }
/// <summary> /// Construct the extension /// </summary> public IEnumerable <Extension> Construct(IIdentifiedEntity modelObject) { if (modelObject is Core.Model.Roles.Patient patient) { // citizenship? foreach (var citizenshipExtension in patient.LoadCollection(o => o.Relationships).Where(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Citizen)) { var citizenPlace = citizenshipExtension.LoadProperty(o => o.TargetEntity); var isoCode = citizenPlace.GetIdentifiers().FirstOrDefault(o => o.AuthorityKey == AssigningAuthorityKeys.Iso3166CountryCode); if (isoCode != null) { yield return(new Extension(this.Uri.ToString(), new CodeableConcept($"urn:oid:{isoCode.AuthorityXml.Oid}", isoCode.Value))); } } } }
/// <summary> /// Load collection /// </summary> /// <param name="propertyType">Type of the property.</param> /// <param name="entity">The entity.</param> /// <returns>IList.</returns> internal static IList LoadCollection(Type propertyType, IIdentifiedEntity entity) { MethodInfo methodInfo = null; var key = entity.Key; var versionKey = (entity as IVersionedEntity)?.VersionSequence; // Load if (!m_relatedLoadAssociations.TryGetValue(propertyType, out methodInfo)) { if (versionKey.HasValue && typeof(IVersionedAssociation).IsAssignableFrom(propertyType.StripGeneric())) { methodInfo = typeof(ObjectExpander).GetRuntimeMethod(nameof(LoadCollection), new Type[] { typeof(Guid), typeof(decimal?) }).MakeGenericMethod(propertyType.StripGeneric()); } else { methodInfo = typeof(ObjectExpander).GetRuntimeMethod(nameof(LoadCollection), new Type[] { typeof(Guid) }).MakeGenericMethod(propertyType.StripGeneric()); } lock (s_syncLock) if (!m_relatedLoadAssociations.ContainsKey(propertyType)) { m_relatedLoadAssociations.Add(propertyType, methodInfo); } } IList listValue = null; if (methodInfo.GetParameters().Length == 2) { listValue = methodInfo.Invoke(null, new object[] { key, versionKey }) as IList; } else { listValue = methodInfo.Invoke(null, new object[] { key }) as IList; } if (propertyType.GetTypeInfo().IsAssignableFrom(listValue.GetType().GetTypeInfo())) { return(listValue); } else { var retVal = Activator.CreateInstance(propertyType, listValue); return(retVal as IList); } }
/// <summary> /// Ensures a model has been persisted /// </summary> public static IIdentifiedEntity EnsureExists(this IIdentifiedEntity me, DataContext context, IPrincipal principal) { if (me == null) { return(null); } // Me var vMe = me as IVersionedEntity; String dkey = String.Format("{0}.{1}", me.GetType().FullName, me.Key); IIdentifiedEntity existing = me.TryGetExisting(context, principal); var idpInstance = AdoAuditPersistenceService.GetPersister(me.GetType()); // Existing exists? if (existing != null && me.Key.HasValue) { // Exists but is an old version if ((existing as IVersionedEntity)?.VersionKey != vMe?.VersionKey && vMe?.VersionKey != null && vMe?.VersionKey != Guid.Empty) { // Update method IVersionedEntity updated = idpInstance.Update(context, me) as IVersionedEntity; me.Key = updated.Key; if (vMe != null) { vMe.VersionKey = (updated as IVersionedEntity).VersionKey; } return(updated); } return(existing); } else if (existing == null) // Insert { IIdentifiedEntity inserted = idpInstance.Insert(context, me) as IIdentifiedEntity; me.Key = inserted.Key; if (vMe != null) { vMe.VersionKey = (inserted as IVersionedEntity).VersionKey; } return(inserted); } return(existing); }
/// <summary> /// Ensures a model has been persisted /// </summary> public static void EnsureExists(this IIdentifiedEntity me, ModelDataContext context, IPrincipal principal) { // Me var vMe = me as IVersionedEntity; String dkey = String.Format("{0}.{1}", me.GetType().FullName, me.Key); IIdentifiedEntity existing = me.TryGetExisting(context, principal); var idpType = typeof(IDataPersistenceService <>).MakeGenericType(me.GetType()); var idpInstance = ApplicationContext.Current.GetService(idpType); // Existing exists? if (existing != null && me.Key.HasValue) { // Exists but is an old version if ((existing as IVersionedEntity)?.VersionKey != vMe?.VersionKey && vMe?.VersionKey != null && vMe?.VersionKey != Guid.Empty) { // Update method var updateMethod = idpInstance.GetType().GetRuntimeMethods().SingleOrDefault(o => o.Name == "Update" && o.GetParameters().Length == 3 && o.GetParameters()[0].ParameterType == typeof(ModelDataContext)); if (updateMethod != null) { IVersionedEntity updated = updateMethod.Invoke(idpInstance, new object[] { context, me, principal }) as IVersionedEntity; me.Key = updated.Key; if (vMe != null) { vMe.VersionKey = (updated as IVersionedEntity).VersionKey; } } } } else // Insert { var insertMethod = idpInstance.GetType().GetRuntimeMethods().SingleOrDefault(o => o.Name == "Insert" && o.GetParameters().Length == 3 && o.GetParameters()[0].ParameterType == typeof(ModelDataContext)); if (insertMethod != null) { IIdentifiedEntity inserted = insertMethod.Invoke(idpInstance, new object[] { context, me, principal }) as IIdentifiedEntity; me.Key = inserted.Key; if (vMe != null) { vMe.VersionKey = (inserted as IVersionedEntity).VersionKey; } } } }
/// <summary> /// Updates a keyed delay load field if needed /// </summary> public static void UpdateParentKeys(this IIdentifiedEntity instance, PropertyInfo field) { var delayLoadProperty = field.GetCustomAttribute <SerializationReferenceAttribute>(); if (delayLoadProperty == null || String.IsNullOrEmpty(delayLoadProperty.RedirectProperty)) { return; } var value = field.GetValue(instance) as IIdentifiedEntity; if (value == null) { return; } // Get the delay load key property! var keyField = instance.GetType().GetRuntimeProperty(delayLoadProperty.RedirectProperty); keyField.SetValue(instance, value.Key); }
public static string GetStream(this IIdentifiedEntity entity) { return(entity.GetStreamFor(entity.GetIdentityValue())); }
/// <summary> /// Get the identifier /// </summary> public static Identifier <Guid> Id(this IIdentifiedEntity me) { // TODO: My AA return(new Identifier <Guid>(me.Key.Value)); }
/// <summary> /// Try get by classifier /// </summary> public static IIdentifiedEntity TryGetExisting(this IIdentifiedEntity me, LocalDataContext context, bool forceDbSearch = false) { // Is there a classifier? var idpInstance = LocalPersistenceService.GetPersister(me.GetType()) as ILocalPersistenceService; if (idpInstance == null) { return(null); } //if (me.Key?.ToString() == "e4d3350b-b0f5-45c1-80ba-49e3844cbcc8") // System.Diagnostics.Debugger.Break(); IIdentifiedEntity existing = null; if (me.Key != null) { existing = context.TryGetCacheItem(me.Key.Value); } if (existing != null) { return(existing); } else if (!context.Connection.IsInTransaction) { existing = context.TryGetData(me.Key.Value.ToString()) as IdentifiedData; } else if (me.Key.HasValue) { existing = context.FindTransactedItem(me.Key.Value); } if (forceDbSearch && me.Key.HasValue) { ApplicationContext.Current.GetService <IDataCachingService>().Remove(me.Key.Value); } // Is the key not null? if (me.Key != Guid.Empty && me.Key != null && existing == null) { existing = idpInstance.Get(context, me.Key.Value) as IIdentifiedEntity; } var classAtt = me.GetType().GetTypeInfo().GetCustomAttribute <KeyLookupAttribute>(); if (classAtt != null && existing == null) { // Get the domain type var dataType = LocalPersistenceService.Mapper.MapModelType(me.GetType()); var tableMap = TableMapping.Get(dataType); // Get the classifier attribute value var classProperty = me.GetType().GetRuntimeProperty(classAtt.UniqueProperty); object classifierValue = classProperty.GetValue(me); // Get the classifier // Is the classifier a UUID'd item? if (classifierValue is IIdentifiedEntity) { classifierValue = (classifierValue as IIdentifiedEntity).Key.Value; classProperty = me.GetType().GetRuntimeProperty(classProperty.GetCustomAttribute <SerializationReferenceAttribute>()?.RedirectProperty ?? classProperty.Name); } // Column var column = tableMap.GetColumn(LocalPersistenceService.Mapper.MapModelProperty(me.GetType(), dataType, classProperty)); // Now we want to query SqlStatement stmt = new SqlStatement().SelectFrom(dataType) .Where($"{column.Name} = ?", classifierValue).Build(); var mapping = context.Connection.GetMapping(dataType); var dataObject = context.Connection.Query(mapping, stmt.SQL, stmt.Arguments.ToArray()).FirstOrDefault(); if (dataObject != null) { existing = idpInstance.ToModelInstance(dataObject, context) as IIdentifiedEntity; } } if (existing != null && me.Key.HasValue) { context.AddData(me.Key.Value.ToString(), existing); } return(existing); }
/// <summary> /// Try get by classifier /// </summary> public static IIdentifiedEntity TryGetExisting(this IIdentifiedEntity me, DataContext context, IPrincipal principal, bool forceDatabase = false) { // Is there a classifier? var idpInstance = AdoAuditPersistenceService.GetPersister(me.GetType()) as IAdoPersistenceService; var cacheService = ApplicationServiceContext.Current.GetService <IDataCachingService>(); IIdentifiedEntity existing = null; // Forcing from database load from if (forceDatabase && me.Key.HasValue) { // HACK: This should really hit the database instead of just clearing the cache ApplicationServiceContext.Current.GetService <IDataCachingService>()?.Remove(me.Key.Value); } //var tableType = AdoPersistenceService.GetMapper().MapModelType(me.GetType()); //if (me.GetType() != tableType) //{ // var tableMap = TableMapping.Get(tableType); // var dbExisting = context.FirstOrDefault(tableType, context.CreateSqlStatement().SelectFrom(tableType).Where($"{tableMap.Columns.FirstOrDefault(o=>o.IsPrimaryKey).Name}=?", me.Key.Value)); // if (dbExisting != null) // existing = idpInstance.ToModelInstance(dbExisting, context, principal) as IIdentifiedEntity; //} if (me.Key != Guid.Empty && me.Key != null) { existing = idpInstance.Get(context, me.Key.Value) as IIdentifiedEntity; } var classAtt = me.GetType().GetCustomAttribute <KeyLookupAttribute>(); if (classAtt != null && existing == null) { // Get the domain type var dataType = AdoAuditPersistenceService.GetMapper().MapModelType(me.GetType()); var tableMap = TableMapping.Get(dataType); // Get the classifier attribute value var classProperty = me.GetType().GetProperty(classAtt.UniqueProperty); object classifierValue = classProperty.GetValue(me); // Get the classifier // Is the classifier a UUID'd item? if (classifierValue is IIdentifiedEntity) { classifierValue = (classifierValue as IIdentifiedEntity).Key.Value; classProperty = me.GetType().GetProperty(classProperty.GetCustomAttribute <SerializationReferenceAttribute>()?.RedirectProperty ?? classProperty.Name); } // Column var column = tableMap.GetColumn(AdoAuditPersistenceService.GetMapper().MapModelProperty(me.GetType(), dataType, classProperty)); // Now we want to query SqlStatement stmt = context.CreateSqlStatement().SelectFrom(dataType) .Where($"{column.Name} = ?", classifierValue); Guid objIdCache = Guid.Empty; IDbIdentified dataObject = null; // We've seen this before String classKey = $"{dataType}.{classifierValue}"; if (m_classIdCache.TryGetValue(classKey, out objIdCache)) { existing = cacheService?.GetCacheItem(objIdCache) as IdentifiedData ?? context.GetCacheCommit(objIdCache); } if (existing == null) { dataObject = context.FirstOrDefault(dataType, stmt) as IDbIdentified; if (dataObject != null) { lock (m_classIdCache) if (!m_classIdCache.ContainsKey(classKey)) { m_classIdCache.Add(classKey, dataObject.Key); } var existCache = cacheService?.GetCacheItem((dataObject as IDbIdentified).Key); if (existCache != null) { existing = existCache as IdentifiedData; } else { existing = idpInstance.ToModelInstance(dataObject, context) as IIdentifiedEntity; } } } } return(existing); }
/// <summary> /// Returns true if the property has been loaded /// </summary> public static bool WasLoaded(this IIdentifiedEntity me, String propertyName) { var loadCheck = new PropertyLoadCheck(propertyName); return(me.GetAnnotations <PropertyLoadCheck>().Contains(loadCheck)); }
/// <summary> /// Runs all registered extensions on the object /// </summary> /// <param name="appliedExtensions">The extensions that were applied to the object</param> /// <param name="applyTo">The object to which the extensions are being applied</param> /// <param name="me">The SanteDB canonical model to apply to</param> public static IEnumerable <Extension> CreateExtensions(this IIdentifiedEntity me, ResourceType applyTo, out IEnumerable <IFhirExtensionHandler> appliedExtensions) { appliedExtensions = s_extensionHandlers.Where(o => o.AppliesTo == null || o.AppliesTo == applyTo); return(appliedExtensions.SelectMany(o => o.Construct(me))); }
/// <summary> /// Get a MDM Master for the specified local key /// </summary> public abstract IMdmMaster CreateMasterContainerForMasterEntity(IIdentifiedEntity masterObject);
/// <summary> /// Ensures a model has been persisted /// </summary> public static IIdentifiedEntity EnsureExists(this IIdentifiedEntity me, DataContext context, bool createIfNotExists = true, Type ensureType = null) { if (me == null) { return(null); } // Me var serviceInstance = ApplicationServiceContext.Current.GetService <AdoPersistenceService>(); var vMe = me as IVersionedEntity; var idpInstance = serviceInstance.GetPersister(ensureType ?? me.GetType()); IIdentifiedEntity existing = me.TryGetExisting(context) ?? idpInstance.Get(context, me.Key.GetValueOrDefault()) as IIdentifiedEntity; // Don't touch the child just return reference if (!serviceInstance.GetConfiguration().AutoInsertChildren || !createIfNotExists) { if (existing != null) { if (me.Key != existing.Key || vMe?.VersionKey != (existing as IVersionedEntity)?.VersionKey) { me.CopyObjectData(existing); // copy data into reference } return(existing); } else { throw new KeyNotFoundException(me.Key.Value.ToString()); } } // Existing exists? if (existing != null && me.Key.HasValue) { // Exists but is an old version if ((existing as IVersionedEntity)?.VersionSequence < vMe?.VersionSequence && vMe?.VersionKey != null && vMe?.VersionKey != Guid.Empty) { // Update method IVersionedEntity updated = idpInstance.Update(context, me) as IVersionedEntity; me.Key = updated.Key; if (vMe != null) { vMe.VersionKey = (updated as IVersionedEntity).VersionKey; } return(updated); } return(existing); } else if (existing == null) // Insert { IIdentifiedEntity inserted = idpInstance.Insert(context, me) as IIdentifiedEntity; me.Key = inserted.Key; if (vMe != null) { vMe.VersionKey = (inserted as IVersionedEntity).VersionKey; } return(inserted); } return(existing); }
public static string GetStreamFor(this IIdentifiedEntity entity, object identity) { return(entity.GetTypeId() + ":" + identity); }
/// <summary> /// Delay load property /// </summary> public static IEnumerable <TReturn> LoadCollection <TReturn>(this IIdentifiedEntity me, string propertyName, bool forceReload = false) { return(me.LoadProperty(propertyName, forceReload) as IEnumerable <TReturn> ?? new List <TReturn>()); }
/// <summary> /// Delay load property /// </summary> public static TReturn LoadProperty <TReturn>(this IIdentifiedEntity me, string propertyName, bool forceReload = false) { return((TReturn)me.LoadProperty(propertyName, forceReload)); }
public static string GetTypeId(this IIdentifiedEntity entity) { return(entity.GetType().FullName); }
/// <summary> /// Delay load property /// </summary> public static object LoadProperty(this IIdentifiedEntity me, string propertyName, bool forceReload = false) { if (me == null) { return(null); } var propertyToLoad = me.GetType().GetRuntimeProperty(propertyName); if (propertyToLoad == null) { return(null); } var currentValue = propertyToLoad.GetValue(me); var loadCheck = new PropertyLoadCheck(propertyName); if (!forceReload && (me.GetAnnotations <PropertyLoadCheck>().Contains(loadCheck) || me.GetAnnotations <String>().Contains(SanteDBConstants.NoDynamicLoadAnnotation))) { return(currentValue); } else if (forceReload) { currentValue = null; } try { if (typeof(IList).IsAssignableFrom(propertyToLoad.PropertyType)) // Collection we load by key { if ((currentValue == null || (currentValue as IList)?.Count == 0) && me.Key.HasValue) { var mi = typeof(IEntitySourceProvider).GetGenericMethod(nameof(IEntitySourceProvider.GetRelations), new Type[] { propertyToLoad.PropertyType.StripGeneric() }, new Type[] { typeof(Guid?[]) }); object loaded = null; if (me is ITaggable taggable && taggable.TryGetTag(SanteDBConstants.AlternateKeysTag, out ITag altKeys)) { loaded = Activator.CreateInstance(propertyToLoad.PropertyType, mi.Invoke(EntitySource.Current.Provider, new Object[] { altKeys.Value.Split(',').Select(o => (Guid?)Guid.Parse(o)).Union(new Guid?[] { me.Key }).ToArray() })); } else { loaded = Activator.CreateInstance(propertyToLoad.PropertyType, mi.Invoke(EntitySource.Current.Provider, new object[] { new Guid?[] { me.Key.Value } })); } propertyToLoad.SetValue(me, loaded); return(loaded); } return(currentValue); } else if (currentValue == null) { var keyValue = propertyToLoad.GetSerializationRedirectProperty()?.GetValue(me) as Guid?; if (keyValue.GetValueOrDefault() == default(Guid)) { return(currentValue); } else { var mi = typeof(IEntitySourceProvider).GetGenericMethod(nameof(IEntitySourceProvider.Get), new Type[] { propertyToLoad.PropertyType }, new Type[] { typeof(Guid?) }); var loaded = mi.Invoke(EntitySource.Current.Provider, new object[] { keyValue }); propertyToLoad.SetValue(me, loaded); return(loaded); } } else { return(currentValue); } }
/// <summary> /// Ensures a model has been persisted /// </summary> public static IIdentifiedEntity EnsureExists(this IIdentifiedEntity me, DataContext context, IPrincipal principal) { if (me == null) { return(null); } // Me var vMe = me as IVersionedEntity; String dkey = String.Format("{0}.{1}", me.GetType().FullName, me.Key); IIdentifiedEntity existing = me.TryGetExisting(context, principal); var idpInstance = AdoPersistenceService.GetPersister(me.GetType()); // Don't touch the child just return reference if (!AdoPersistenceService.GetConfiguration().AutoInsertChildren) { if (existing != null) { if (me.Key != existing.Key || vMe?.VersionKey != (existing as IVersionedEntity)?.VersionKey) { me.CopyObjectData(existing); // copy data into reference } return(existing); } else { throw new KeyNotFoundException(me.Key.Value.ToString()); } } // Existing exists? if (existing != null && me.Key.HasValue) { // Exists but is an old version if ((existing as IVersionedEntity)?.VersionKey != vMe?.VersionKey && vMe?.VersionKey != null && vMe?.VersionKey != Guid.Empty) { // Update method IVersionedEntity updated = idpInstance.Update(context, me, principal) as IVersionedEntity; me.Key = updated.Key; if (vMe != null) { vMe.VersionKey = (updated as IVersionedEntity).VersionKey; } return(updated); } return(existing); } else if (existing == null) // Insert { IIdentifiedEntity inserted = idpInstance.Insert(context, me, principal) as IIdentifiedEntity; me.Key = inserted.Key; if (vMe != null) { vMe.VersionKey = (inserted as IVersionedEntity).VersionKey; } return(inserted); } return(existing); }