Esempio n. 1
0
        /// <summary>
        /// Return the names of all persistent (mapped) classes that extend or implement the
        /// given class or interface, accounting for implicit/explicit polymorphism settings
        /// and excluding mapped subclasses/joined-subclasses of other classes in the result.
        /// </summary>
        public string[] GetImplementors(string entityOrClassName)
        {
            string[] knownMap;
            if (entityNameImplementorsMap.TryGetValue(entityOrClassName, out knownMap))
            {
                return(knownMap);
            }
            System.Type clazz = null;

            // NH Different implementation for performance: a class without at least a namespace sure can't be found by reflection
            if (entityOrClassName.IndexOf('.') > 0)
            {
                IEntityPersister checkPersister;
                // NH Different implementation: we have better performance checking, first of all, if we know the class
                // and take the System.Type directly from the persister (className have high probability to be entityName at least using Criteria or Linq)
                if (entityPersisters.TryGetValue(entityOrClassName, out checkPersister))
                {
                    if (!checkPersister.EntityMetamodel.HasPocoRepresentation)
                    {
                        // we found the persister but it is a dynamic entity without class
                        knownMap = new[] { entityOrClassName };
                        entityNameImplementorsMap[entityOrClassName] = knownMap;
                        return(knownMap);
                    }
                    // NH : take care with this because we are forcing the Poco EntityMode
                    clazz = checkPersister.GetMappedClass(EntityMode.Poco);
                }

                if (clazz == null)
                {
                    try
                    {
                        clazz = ReflectHelper.ClassForFullNameOrNull(entityOrClassName);
                    }
                    catch (Exception)
                    {
                        clazz = null;
                    }
                }
            }

            if (clazz == null)
            {
                // try to get the class from imported names
                string importedName = GetImportedClassName(entityOrClassName);
                if (importedName != null)
                {
                    clazz = System.Type.GetType(importedName, false);
                }
            }

            if (clazz == null)
            {
                knownMap = new[] { entityOrClassName };
                entityNameImplementorsMap[entityOrClassName] = knownMap;
                return(knownMap);                //for a dynamic-class
            }

            var results = new List <string>();

            foreach (var q in entityPersisters.Values.OfType <IQueryable>())
            {
                string registeredEntityName = q.EntityName;
                // NH: as entity-name we are using the FullName but in HQL we allow just the Name, the class is mapped even when its FullName match the entity-name
                bool isMappedClass = entityOrClassName.Equals(registeredEntityName) || clazz.FullName.Equals(registeredEntityName);
                if (q.IsExplicitPolymorphism)
                {
                    if (isMappedClass)
                    {
                        knownMap = new[] { registeredEntityName };
                        entityNameImplementorsMap[entityOrClassName] = knownMap;
                        return(knownMap);                        // NOTE EARLY EXIT
                    }
                }
                else
                {
                    if (isMappedClass)
                    {
                        results.Add(registeredEntityName);
                    }
                    else
                    {
                        if (IsMatchingImplementor(entityOrClassName, clazz, q))
                        {
                            bool assignableSuperclass;
                            if (q.IsInherited)
                            {
                                System.Type mappedSuperclass = GetEntityPersister(q.MappedSuperclass).GetMappedClass(EntityMode.Poco);
                                assignableSuperclass = clazz.IsAssignableFrom(mappedSuperclass);
                            }
                            else
                            {
                                assignableSuperclass = false;
                            }
                            if (!assignableSuperclass)
                            {
                                results.Add(registeredEntityName);
                            }
                        }
                    }
                }
            }
            knownMap = results.ToArray();
            entityNameImplementorsMap[entityOrClassName] = knownMap;
            return(knownMap);
        }
Esempio n. 2
0
        /// <summary>
        /// Return the names of all persistent (mapped) classes that extend or implement the
        /// given class or interface, accounting for implicit/explicit polymorphism settings
        /// and excluding mapped subclasses/joined-subclasses of other classes in the result.
        /// </summary>
        public string[] GetImplementors(string className)
        {
            System.Type clazz = null;

            // NH Different implementation for performance: a class without at least a namespace sure can't be found by reflection
            if (className.IndexOf('.') > 0)
            {
                IEntityPersister checkPersister;
                // NH Different implementation: we have better performance checking, first of all, if we know the class
                // and take the System.Type directly from the persister (className have high probability to be entityName)
                if (entityPersisters.TryGetValue(className, out checkPersister))
                {
                    if (!checkPersister.EntityMetamodel.HasPocoRepresentation)
                    {
                        // we found the persister but it is a dynamic entity without class
                        return(new[] { className });
                    }
                    // NH : take care with this because we are forcing the Poco EntityMode
                    clazz = checkPersister.GetMappedClass(EntityMode.Poco);
                }

                if (clazz == null)
                {
                    try
                    {
                        clazz = ReflectHelper.ClassForFullNameOrNull(className);
                    }
                    catch (Exception)
                    {
                        clazz = null;
                    }
                }
            }

            if (clazz == null)
            {
                return(new[] { className });              //for a dynamic-class
            }

            List <string> results = new List <string>();

            foreach (IEntityPersister p in entityPersisters.Values)
            {
                IQueryable q = p as IQueryable;
                if (q != null)
                {
                    string testClassName = q.EntityName;
                    bool   isMappedClass = className.Equals(testClassName);
                    if (q.IsExplicitPolymorphism)
                    {
                        if (isMappedClass)
                        {
                            return(new string[] { testClassName });                          // NOTE EARLY EXIT
                        }
                    }
                    else
                    {
                        if (isMappedClass)
                        {
                            results.Add(testClassName);
                        }
                        else
                        {
                            System.Type mappedClass = q.GetMappedClass(EntityMode.Poco);
                            if (mappedClass != null && clazz.IsAssignableFrom(mappedClass))
                            {
                                bool assignableSuperclass;
                                if (q.IsInherited)
                                {
                                    System.Type mappedSuperclass = GetEntityPersister(q.MappedSuperclass).GetMappedClass(EntityMode.Poco);
                                    assignableSuperclass = clazz.IsAssignableFrom(mappedSuperclass);
                                }
                                else
                                {
                                    assignableSuperclass = false;
                                }
                                if (!assignableSuperclass)
                                {
                                    results.Add(testClassName);
                                }
                            }
                        }
                    }
                }
            }
            return(results.ToArray());
        }