Example #1
0
        /// <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);
        }
Example #2
0
        /// <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;
                    }
                }
            }
        }
Example #3
0
        /// <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>
        /// 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);
            }
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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);
        }
Example #7
0
        /// <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>
        /// 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);
        }
        /// <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);
                }
            }
Example #10
0
        /// <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);
        }
Example #11
0
 public static string GetTypeId(this IIdentifiedEntity entity)
 {
     return(entity.GetType().FullName);
 }