예제 #1
0
        private async Task UpdateEntityAssociationAsync(
            EntityAssociation association,
            EntityInfo entityInfo,
            AbstractEntityPersister persister,
            EntityIdMap entitiesIdMap,
            DependencyGraph dependencyGraph,
            ConfiguredSessionProvider sessionProvider, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            var dbEntity        = entityInfo.Entity;
            var originalFkValue = await(GetClientForeignKeyValueAsync(association, entityInfo, entitiesIdMap, true, sessionProvider, cancellationToken)).ConfigureAwait(false);

            TryAddToGraphAndUpdateParent(entityInfo, entitiesIdMap, dependencyGraph, originalFkValue, association, true, true, sessionProvider, out _);

            var newFkValue = await(GetClientForeignKeyValueAsync(association, entityInfo, entitiesIdMap, false, sessionProvider, cancellationToken)).ConfigureAwait(false);

            TryAddToGraphAndUpdateParent(entityInfo, entitiesIdMap, dependencyGraph, newFkValue, association, false, true, sessionProvider, out var parentEntityInfo);

            // Set the entity association (e.g. Order = value)
            var associatedEntity = newFkValue != null
                ? parentEntityInfo?.Entity ?? await(LoadEntityAsync(association.EntityType, newFkValue, sessionProvider, cancellationToken)).ConfigureAwait(false)
                : null;

            persister.SetPropertyValue(
                dbEntity,
                persister.GetPropertyIndex(association.AssociationPropertyName),
                associatedEntity);
        }
예제 #2
0
 /// <summary>
 /// Find a join.  Return the name of the corresponding property.
 /// </summary>
 private static AbstractEntityPersister FindJoinedEntity(SessionFactoryImpl sf, AbstractEntityPersister root, string toTable, string fromField, out string propertyName)
 {
     //   root.ClassMetadata.PropertyTypes.First().Na
     for (int i = 0; i < root.PropertyTypes.Length; i++)
     {
         if (root.PropertyTypes[i].IsAssociationType &&
             !root.PropertyTypes[i].IsCollectionType)
         {
             String[] cols = root.ToColumns(root.PropertyNames[i]);
             if (cols.Length == 1 && cols[0] == fromField)
             {
                 propertyName = root.PropertyNames[i];
                 Type   t          = root.PropertyTypes[i].ReturnedClass;
                 String entityName = sf.TryGetGuessEntityName(t);
                 AbstractEntityPersister persister = (AbstractEntityPersister)sf.GetEntityPersister(entityName);
                 if (persister.TableName == toTable)
                 {
                     return(persister);
                 }
                 // special case for acct mgr
                 if (toTable == "USERINFO" && persister.TableName == "USERSECURITY")
                 {
                     propertyName = propertyName + ".UserInfo";
                     entityName   = "Sage.SalesLogix.Security.UserInfo";
                     return((AbstractEntityPersister)sf.GetEntityPersister(entityName));
                 }
             }
         }
     }
     propertyName = null;
     return(null);
 }
        /// <summary>
        /// Return names of all properties that are defined in the mapped ancestors of the
        /// given persister.  Note that unmapped superclasses are deliberately ignored, because
        /// they shouldn't affect the metadata.
        /// </summary>
        /// <param name="persister"></param>
        /// <returns>set of property names.  Empty if the persister doesn't have a superclass.</returns>
        HashSet <string> GetSuperProperties(AbstractEntityPersister persister)
        {
            HashSet <string> set = new HashSet <String>();

            if (!persister.IsInherited)
            {
                return(set);
            }
            string superClassName = persister.MappedSuperclass;

            if (superClassName == null)
            {
                return(set);
            }

            IClassMetadata superMeta = _sessionFactory.GetClassMetadata(superClassName);

            if (superMeta == null)
            {
                return(set);
            }

            string[] superProps = superMeta.PropertyNames;
            set = new HashSet <string>(superProps);
            set.Add(superMeta.IdentifierPropertyName);
            return(set);
        }
예제 #4
0
        public Boolean DeleteAll()
        {
            AbstractEntityPersister metadata = HibernateHelper.SessionFactory.GetClassMetadata(typeof(T)) as NHibernate.Persister.Entity.AbstractEntityPersister;
            String table = metadata.TableName;

            using (ISession session = HibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        string deleteAll = String.Format("Delete From \"{0}\"", table);
                        session.CreateSQLQuery(deleteAll).ExecuteUpdate();
                        transaction.Commit();
                        return(true);
                    }
                    catch (Exception)
                    {
                        transaction.Rollback();
                        return(false);
                    }
                    finally
                    {
                        session.Disconnect();
                        session.Close();
                    }
                }
            }
        }
예제 #5
0
        public static string GetTableName <T>( )
        {
            IClassMetadata          md  = Connection.Database.Instance.SessionFactory.GetClassMetadata(typeof(T));
            AbstractEntityPersister aep = md as AbstractEntityPersister;

            return(aep.TableName);
            //return new NHibernate.Cfg.Configuration().GetClassMapping(typeof(T)).RootTable.Name;
        }
예제 #6
0
        public EntityBatchFetcher(AbstractEntityPersister persister)
        {
            _parameter = Expression.Parameter(typeof(TEntity));
            var property = Expression.Property(_parameter, persister.IdentifierPropertyName);

            _idExpression   = Expression.Lambda <Func <TEntity, TId> >(property, _parameter);
            _idSelector     = Expression.Lambda <Func <TEntity, object> >(Expression.Convert(property, typeof(object)), _parameter).Compile();
            _containsMethod = ReflectHelper.GetMethod(() => Enumerable.Contains(null, default(TId)));
        }
예제 #7
0
        /// <summary>
        /// Attempt to extract properties from the lookup metadata.
        /// The result of this operation is cached.
        /// </summary>
        /// <param name="lookupName"></param>
        /// <param name="entityTypeName"></param>
        /// <returns></returns>
        internal static LookupPropertyCollection GetLookupProperties(String lookupName, String entityTypeName)
        {
            LookupPropertyCollection result = null;

            if (HttpContext.Current != null &&
                ((result = HttpContext.Current.Cache["LookupProperties$" + entityTypeName + "$" + lookupName] as LookupPropertyCollection) != null))
            {
                return(result);
            }
            result = new LookupPropertyCollection();

            using (var sess = new SessionScopeWrapper())
            {
                Type entityType = Type.GetType(entityTypeName);
                if (entityType == null)
                {
                    throw new ArgumentException("Unable to locate type " + entityTypeName);
                }
                if (entityType.IsInterface)
                {
                    throw new ArgumentException("Must use the concrete class as EntityTypeName (e.g., Sage.SalesLogix.Entities.Contact)");
                }
                String entityName = ((SessionFactoryImpl)sess.SessionFactory).TryGetGuessEntityName(entityType);
                if (entityName == null)
                {
                    throw new ArgumentException("Unable to locate persister for entity type " + entityType.FullName);
                }
                AbstractEntityPersister persister = (AbstractEntityPersister)((SessionFactoryImpl)sess.SessionFactory).GetEntityPersister(entityName);
                foreach (LookupLayoutField lookupField in GetLookupFields(sess, persister.TableName, lookupName))
                {
                    String[] tableField = lookupField.Path.Split(new char[] { ':' });
                    if (persister == null || persister.TableName != tableField[0])
                    {
                        throw new ArgumentException("Invalid lookup data - table name does not match persister table (" + persister.TableName + " vs " + tableField[0] + ") - check EntityName setting");
                    }
                    String propName = DecomposePath((SessionFactoryImpl)sess.SessionFactory, persister, tableField[1], lookupField.Format);
                    if (propName != null)
                    {
                        result.Add(new LookupProperty(propName, lookupField.Caption));
                        // TODO: we should set the property format here
                    }
                }
            }
            if (LOG.IsDebugEnabled)
            {
                foreach (LookupProperty prop in result)
                {
                    LOG.Debug("Using property '" + prop.PropertyName + "' with header '" + prop.PropertyHeader + "'");
                }
            }
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Cache["LookupProperties$" + entityTypeName + "$" + lookupName] = result;
            }
            return(result);
        }
예제 #8
0
        public void TestFormatOwner()
        {
            String entityName = "Sage.SalesLogix.Entities.Contact";

            using (var sess = new SessionScopeWrapper())
            {
                SessionFactoryImpl      sf        = (SessionFactoryImpl)sess.SessionFactory;
                AbstractEntityPersister persister = (AbstractEntityPersister)(sf.GetEntityPersister(entityName));
                Assert.AreEqual("Owner.OwnerDescription", SimpleLookup.DecomposePath(sf, persister, "SECCODEID", "8"));
            }
        }
예제 #9
0
        public override string GetAuditNoteForComponentProperty(AbstractEntityPersister persister, ComponentType componentType, int propertyIndexToAudit)
        {
            string componentPropertyName = persister.PropertyNames[propertyIndexToAudit];

            object oldComponentValue = _oldStates[propertyIndexToAudit];
            object newComponentValue = _newStates[propertyIndexToAudit];

            string note = GetAuditNoteForComponent(persister, componentType, componentPropertyName, new UpdateComponentAuditStrategy(oldComponentValue, newComponentValue));

            return(note);
        }
예제 #10
0
        public void TestFormatUserName()
        {
            String entityName = "Sage.SalesLogix.Entities.Contact";

            using (var sess = new SessionScopeWrapper())
            {
                SessionFactoryImpl      sf        = (SessionFactoryImpl)sess.SessionFactory;
                AbstractEntityPersister persister = (AbstractEntityPersister)(sf.GetEntityPersister(entityName));
                Assert.AreEqual("AccountManager.UserInfo.UserName", SimpleLookup.DecomposePath(sf, persister, "ACCOUNTMANAGERID", "6"));
            }
        }
        private void AddIdentifierProperties(
            AbstractEntityPersister persister,
            EntityType entityType,
            ModelConfiguration modelConfiguration,
            EntityMetadata entityMetadata,
            BreezeMetadata metadata)
        {
            // Add the identifier properties only for the root class
            if (persister.IsInherited)
            {
                return;
            }

            if (persister.HasIdentifierProperty)
            {
                var memberConfiguration = modelConfiguration.GetMember(persister.IdentifierPropertyName);
                var dataProperty        = CreateDataProperty(
                    persister.IdentifierPropertyName,
                    persister.IdentifierType,
                    true,
                    false,
                    false,
                    memberConfiguration,
                    entityType,
                    persister.Factory);
                entityType.DataProperties.Insert(0, dataProperty);
            }
            else if (persister.IdentifierType is IAbstractComponentType componentType)
            {
                modelConfiguration = _breezeConfigurator.GetModelConfiguration(componentType.ReturnedClass);
                AddDataProperties(
                    componentType.PropertyNames,
                    componentType.Subtypes,
                    componentType.PropertyNullability,
                    null,
                    null,
                    true,
                    entityType,
                    modelConfiguration,
                    metadata,
                    persister.Factory);
                AddAssociationProperties(
                    componentType.PropertyNames,
                    componentType.Subtypes,
                    true,
                    i => componentType.GetCascadeStyle(i),
                    entityType,
                    null,
                    modelConfiguration,
                    entityMetadata);
            }
        }
예제 #12
0
        /// <summary>
        /// Path represents path to a field, based at origin.
        /// Return the field object.
        /// A field path is normally of the form:
        /// Source Table:Path
        /// where Path is recursively defined as either:
        /// FieldName
        /// or
        /// From Field=To Field.To Table!Path
        /// </summary>
        /// <param name="sf"></param>
        /// <param name="root"></param>
        /// <param name="path"></param>
        /// <param name="format"></param>
        internal static String DecomposePath(SessionFactoryImpl sf, AbstractEntityPersister root, String path, String format)
        {
            String[] parts;

            parts = path.Split(new char[] { '!' }, 2);
            if (parts.Length == 1)
            {
                // field name
                // remove initial "@" (this is used to indicate calculated fields)
                if (parts[0][0] == '@')
                {
                    parts[0] = parts[0].Substring(1);
                }
                String fieldName = parts[0].ToUpper();
                for (int i = 0; i < root.PropertyTypes.Length; i++)
                {
                    IType propType = root.PropertyTypes[i];
                    if (propType.IsCollectionType)
                    {
                        continue;
                    }
                    String   propName = root.PropertyNames[i];
                    String[] columns  = root.ToColumns(propName);
                    if (columns.Length == 1 && columns[0].ToUpper() == fieldName)
                    {
                        return(FormatProperty(propName, propType, format));
                    }
                }

                LOG.Warn("Unable to locate property by column - " + parts[0]);
                return(null);
            }
            else
            {
                String newpath = parts[1];  // part after the exclamation mark
                Match  matches = _fieldPathRegexp.Match(parts[0]);
                if (!matches.Success)
                {
                    throw new ArgumentException("Path did not match field expression pattern: " + parts[0]);
                }
                System.Diagnostics.Debug.Assert(matches.Groups.Count == 5, "Number of Groups should have been 5, was " + matches.Groups.Count + " (path = " + parts[0] + ")");
                String toTable   = matches.Groups[4].Value;
                String fromField = matches.Groups[1].Value;
                String propertyName;
                root = FindJoinedEntity(sf, root, toTable, fromField, out propertyName);
                if (root == null)
                {
                    throw new ArgumentException("Unable to locate linked property " + toTable + " via " + fromField + "!");
                }
                return(propertyName + "." + DecomposePath(sf, root, newpath, format));
            }
        }
예제 #13
0
        // e.g. componentPropertyNameChain = "Name.First" for patient first name
        internal string GetAuditNoteForComponent(AbstractEntityPersister persister, ComponentType componentType, string componentPropertyNameChain, IComponentAuditStrategy propertyAuditStrategy)
        {
            var noteBulder = new StringBuilder();

            Type componentDotNetType = componentType.ReturnedClass;

            foreach (PropertyInfo propertyInfo in componentDotNetType.GetProperties())
            {
                if (propertyAuditStrategy.IsExcludedFromAudit(propertyInfo))
                {
                    continue;
                }

                var ignoreMappingTypeAttributes = propertyInfo.GetCustomAttributes(typeof(IgnoreMappingAttribute), false);
                if (ignoreMappingTypeAttributes.Length != 0)
                {
                    continue;
                }

                string propertyName = propertyInfo.Name;
                var    wholeComponentPropertyNameChain = string.Format("{0}.{1}", componentPropertyNameChain, propertyName);

                var subComponentType =
                    componentType.Subtypes.FirstOrDefault(p => p.ReturnedClass.FullName == propertyInfo.PropertyType.FullName && p.IsComponentType)
                    as
                    ComponentType;

                string note;

                if (subComponentType == null)
                {
                    string columnName = string.Join(",", persister.GetPropertyColumnNames(wholeComponentPropertyNameChain));

                    note = propertyAuditStrategy.GetAuditNoteForNonComponentProperty(propertyInfo, columnName);
                }
                else
                {
                    note = GetAuditNoteForComponent(
                        persister,
                        subComponentType,
                        wholeComponentPropertyNameChain,
                        propertyAuditStrategy.GetComponentPropertyAuditStrategy(propertyInfo));
                }

                if (!string.IsNullOrWhiteSpace(note))
                {
                    noteBulder.AppendLine();
                }
            }

            return(noteBulder.ToString().Trim());
        }
        /// <summary>
        /// Initialize and configure the data source using given properties.
        /// Called when space is started.
        /// </summary>
        /// <param name="properties">Propeties to initialize by.</param>
        public override void Init(Dictionary <string, string> properties)
        {
            base.Init(properties);

            _enumeratorLoadFetchSize   = GetIntProperty("EnumeratorLoadFetchSize", _enumeratorLoadFetchSize);
            _initialLoadChunkSize      = GetIntProperty("InitialLoadChunkSize", _initialLoadChunkSize);
            _performOrderById          = GetBoolProperty("PerformOrderById", _performOrderById);
            _initialLoadThreadPoolSize = GetIntProperty("InitialLoadThreadPoolSize", _initialLoadThreadPoolSize);
            _useMerge = GetBoolProperty("UseMerge", _useMerge);

            // only configure a session factory if it is not injected
            if (_sessionFactory == null)
            {
                string nhibernateFile   = GetFileProperty(NHibernateConfigProperty);
                string hbmDirectory     = GetFileProperty(NHibernateHbmDirectory);
                string connectionString = GetProperty(NHibernateConnectionStringProperty);
                _sessionFactory = SessionFactoryBuilder.GetFactory(nhibernateFile, hbmDirectory, connectionString);
            }
            // only extract managed entries if it wasn't injected
            if (_managedEntries == null)
            {
                List <string> managedEntriesList = new List <string>();
                IDictionary <string, IClassMetadata> allClassMetadata = _sessionFactory.GetAllClassMetadata();
                foreach (string type in allClassMetadata.Keys)
                {
                    managedEntriesList.Add(type);
                }
                ManagedEntries = managedEntriesList.ToArray();
            }
            // only extract initial load entries if it wasn't injected
            if (_initialLoadEntries == null)
            {
                List <string> initialLoadEntriesList = new List <string>();
                IDictionary <string, IClassMetadata> allClassMetadata = _sessionFactory.GetAllClassMetadata();
                foreach (KeyValuePair <string, IClassMetadata> entry in allClassMetadata)
                {
                    AbstractEntityPersister entityPersister = (AbstractEntityPersister)entry.Value;
                    string mappedSuperClass = entityPersister.MappedSuperclass;
                    if (mappedSuperClass != null)
                    {
                        IClassMetadata superClassMetadata = allClassMetadata[mappedSuperClass];
                        if (superClassMetadata.GetMappedClass(EntityMode.Map) != null)
                        {
                            //Filter out those who have their super classes mapped
                            continue;
                        }
                    }
                    initialLoadEntriesList.Add(entry.Key);
                }
                InitialLoadEntries = initialLoadEntriesList.ToArray();
            }
        }
예제 #15
0
        public void TestDecomposePath()
        {
            String entityName = "Sage.SalesLogix.Entities.Contact";

            using (var sess = new SessionScopeWrapper())
            {
                SessionFactoryImpl      sf        = (SessionFactoryImpl)sess.SessionFactory;
                AbstractEntityPersister persister = (AbstractEntityPersister)(sf.GetEntityPersister(entityName));
                Assert.AreEqual("LastName", SimpleLookup.DecomposePath(sf, persister, "LASTNAME", "0"));
                Assert.AreEqual("Address.PostalCode", SimpleLookup.DecomposePath(sf, persister, "ADDRESSID=ADDRESSID.ADDRESS!POSTALCODE", "0"));
                Assert.AreEqual("AccountManager.UserInfo.UserName", SimpleLookup.DecomposePath(sf, persister, "ACCOUNTMANAGERID>USERID.USERINFO!USERNAME", "0"));
            }
        }
        private SqlString GenerateSequentialSelect(ILoadable persister)
        {
            //note that this method could easily be moved up to BasicEntityPersister,
            //if we ever needed to reuse it from other subclasses

            //figure out which tables need to be fetched
            AbstractEntityPersister subclassPersister = (AbstractEntityPersister)persister;
            HashedSet <int>         tableNumbers      = new HashedSet <int>();

            string[] props   = subclassPersister.PropertyNames;
            string[] classes = subclassPersister.PropertySubclassNames;
            for (int i = 0; i < props.Length; i++)
            {
                int propTableNumber = GetSubclassPropertyTableNumber(props[i], classes[i]);
                if (IsSubclassTableSequentialSelect(propTableNumber) && !IsSubclassTableLazy(propTableNumber))
                {
                    tableNumbers.Add(propTableNumber);
                }
            }
            if ((tableNumbers.Count == 0))
            {
                return(null);
            }

            //figure out which columns are needed
            List <int> columnNumbers = new List <int>();

            int[] columnTableNumbers = SubclassColumnTableNumberClosure;
            for (int i = 0; i < SubclassColumnClosure.Length; i++)
            {
                if (tableNumbers.Contains(columnTableNumbers[i]))
                {
                    columnNumbers.Add(i);
                }
            }

            //figure out which formulas are needed
            List <int> formulaNumbers = new List <int>();

            int[] formulaTableNumbers = SubclassColumnTableNumberClosure;
            for (int i = 0; i < SubclassFormulaTemplateClosure.Length; i++)
            {
                if (tableNumbers.Contains(formulaTableNumbers[i]))
                {
                    formulaNumbers.Add(i);
                }
            }

            //render the SQL
            return(RenderSelect(ArrayHelper.ToIntArray(tableNumbers), columnNumbers.ToArray(), formulaNumbers.ToArray()));
        }
예제 #17
0
 /// <summary>
 /// Constructs an instance of <see cref="EntityMetadata"/>.
 /// </summary>
 public EntityMetadata(
     AbstractEntityPersister entityPersister,
     Func <object> createInstance,
     IEntityBatchFetcher batchFetcher,
     Type type,
     Type baseType,
     AutoGeneratedKeyType autoGeneratedKeyType,
     string versionPropertyName,
     Type versionPropertyType,
     bool hasCompositeKey,
     IReadOnlyDictionary <string, SyntheticForeignKeyProperty> syntheticForeignKeyProperties,
     IReadOnlyCollection <Type> derivedTypes,
     IReadOnlyCollection <string> derivedPropertyNames,
     IReadOnlyList <string> identifierPropertyNames,
     IReadOnlyList <Func <object, object> > identifierPropertyGetters,
     IReadOnlyList <Type> identifierPropertyTypes,
     IReadOnlyList <DataType> identifierPropertyDataTypes,
     IReadOnlyList <int?> identifierPropertyTypeLengths,
     IReadOnlyCollection <string> foreignKeyPropertyNames,
     IReadOnlyDictionary <string, Association> associations,
     IReadOnlyDictionary <string, EntityAssociation> foreignKeyAssociations,
     IReadOnlyDictionary <string, Func <object, object> > manyToOneIdentifierProperties)
     : base(
         type,
         baseType,
         autoGeneratedKeyType,
         hasCompositeKey,
         syntheticForeignKeyProperties,
         derivedTypes,
         derivedPropertyNames,
         identifierPropertyNames,
         identifierPropertyGetters,
         identifierPropertyTypes,
         identifierPropertyDataTypes,
         identifierPropertyTypeLengths,
         foreignKeyPropertyNames,
         associations)
 {
     EntityPersister               = entityPersister;
     CreateInstance                = createInstance;
     BatchFetcher                  = batchFetcher;
     ForeignKeyAssociations        = foreignKeyAssociations;
     VersionPropertyName           = versionPropertyName;
     VersionPropertyType           = versionPropertyType;
     ManyToOneIdentifierProperties = manyToOneIdentifierProperties;
     AllProperties                 = new HashSet <string>(
         identifierPropertyNames
         .Concat(manyToOneIdentifierProperties.Keys) // We have to add also many-to-one identifier names as identifierPropertyNames does not contain them
         .Concat(entityPersister.PropertyNames)
         .Concat(syntheticForeignKeyProperties.Select(o => o.Key)));
 }
예제 #18
0
        public override string GetAuditNoteForComponentProperty(AbstractEntityPersister persister, ComponentType componentType, int propertyIndexToAudit)
        {
            string componentPropertyName = persister.PropertyNames[propertyIndexToAudit];

            object componentValue = _states[propertyIndexToAudit];

            string note = string.Empty;

            if (componentValue != null)
            {
                note = GetAuditNoteForComponent(persister, componentType, componentPropertyName, new DefaultComponentAuditStrategy(componentValue));
            }

            return(note);
        }
예제 #19
0
        /// <summary>
        /// Render a SqlString for the expression.
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="criteriaQuery"></param>
        /// <param name="enabledFilters"></param>
        /// <returns>
        /// A SqlString that contains a valid Sql fragment.
        /// </returns>
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary <string, IFilter> enabledFilters)
        {
            IEnumerable <Parameter> parameters = criteriaQuery.NewQueryParameter(GetParameterTypedValue(criteria, criteriaQuery));

            Parameter p = null;

            foreach (Parameter p_ in parameters)
            {
                p = p_;
            }

            //Parameter[] p = criteriaQuery.NewQueryParameter(GetTypedValues(criteria, criteriaQuery)[0]).ToArray();
            ISpatialDialect spatialDialect = (ISpatialDialect)criteriaQuery.Factory.Dialect;

            string[] columnsUsingProjection = criteriaQuery.GetColumnsUsingProjection(criteria, this.propertyName);
            IType    typeUsingProjection    = criteriaQuery.GetTypeUsingProjection(criteria, this.propertyName);

            if (typeUsingProjection.IsCollectionType)
            {
                throw new QueryException(string.Format("cannot use collection property ({0}.{1}) directly in a criterion, use ICriteria.CreateCriteria instead", criteriaQuery.GetEntityName(criteria), this.propertyName));
            }
            string[] keyColumns = criteriaQuery.GetIdentifierColumns(criteria);


            string entityType = criteriaQuery.GetEntityName(criteria, this.propertyName);
            AbstractEntityPersister entityPersister = (AbstractEntityPersister)criteriaQuery.Factory.GetEntityPersister(entityType);

            // Only one key column is assumed
            string keyColumn   = keyColumns[0];
            string alias       = criteriaQuery.GetSQLAlias(criteria, this.propertyName);
            string tableName   = entityPersister.TableName;
            int    aliasLength = alias.Length + 1;

            SqlStringBuilder builder = new SqlStringBuilder(10 * columnsUsingProjection.Length);

            for (int i = 0; i < columnsUsingProjection.Length; i++)
            {
                if (i > 0)
                {
                    builder.Add(" AND ");
                }
                string geometryColumn = columnsUsingProjection[i].Remove(0, aliasLength);
                builder.Add(spatialDialect.GetSpatialFilterString(alias, geometryColumn, keyColumn, tableName, p));
            }
            return(builder.ToSqlString());
        }
 /// <summary>
 /// Get the column names for a given property as a comma-delimited string of unbracketed names.
 /// For a collection property, the column name is the inverse foreign key (i.e. the column on
 /// the other table that points back to the persister's table)
 /// </summary>
 /// <param name="persister"></param>
 /// <param name="propertyName"></param>
 /// <returns></returns>
 string GetPropertyColumnNames(AbstractEntityPersister persister, string propertyName, IType propType)
 {
     string[] propColumnNames = null;
     if (propType.IsCollectionType)
     {
         propColumnNames = ((CollectionType)propType).GetReferencedColumns((ISessionFactoryImplementor)this._sessionFactory);
     }
     else
     {
         propColumnNames = persister.GetPropertyColumnNames(propertyName);
     }
     if (propColumnNames == null || propColumnNames.Length == 0)
     {
         // this happens when the property is part of the key
         propColumnNames = persister.KeyColumnNames;
     }
     return(CatColumnNames(propColumnNames));
 }
예제 #21
0
        private static object CopyOnlyForeignKeyProperties(object entity, System.Type entityType,
                                                           AbstractEntityPersister entityMetadata, DeepCloneOptions opts, DeepCloneParentEntity parentEntity)
        {
            var propertyInfos = entityType.GetProperties();

            //Copy only Fks
            foreach (var propertyInfo in propertyInfos
                     .Where(p => opts.CanCloneIdentifier(entityType) || entityMetadata.IdentifierPropertyName != p.Name)
                     .Where(p => !opts.GetIgnoreMembers(entityType).Contains(p.Name))
                     .Where(p => p.GetSetMethod(true) != null))
            {
                IType propertyType;
                try
                {
                    propertyType = entityMetadata.GetPropertyType(propertyInfo.Name);
                }
                catch (Exception)
                {
                    continue;
                }
                if (!NHibernateUtil.IsPropertyInitialized(entity, propertyInfo.Name))
                {
                    continue;
                }
                var propertyValue = propertyInfo.GetValue(entity, null);
                if (!NHibernateUtil.IsInitialized(propertyValue))
                {
                    continue;
                }

                var colNames = entityMetadata.GetPropertyColumnNames(propertyInfo.Name);
                if (!propertyType.IsEntityType)
                {
                    continue;
                }
                //Check if we have a parent entity and that is bidirectional related to the current property (one-to-many)
                if (parentEntity.ReferencedColumns.SequenceEqual(colNames))
                {
                    propertyInfo.SetValue(entity, parentEntity.Entity, null);
                }
            }
            return(entity);
        }
예제 #22
0
        /// <inheritdoc />
        public IEntityBatchFetcher Create(AbstractEntityPersister persister)
        {
            ConstructorInfo constructor;

            if (persister.IdentifierPropertyName != null)
            {
                constructor = typeof(EntityBatchFetcher <,>)
                              .MakeGenericType(persister.MappedClass, persister.IdentifierType.ReturnedClass)
                              .GetConstructor(new[] { typeof(AbstractEntityPersister) });
            }
            else
            {
                constructor = typeof(CompositeEntityBatchFetcher <>)
                              .MakeGenericType(persister.MappedClass)
                              .GetConstructor(new[] { typeof(AbstractEntityPersister) });
            }

            return((IEntityBatchFetcher)constructor.Invoke(new object[] { persister }));
        }
예제 #23
0
        /// <summary>
        /// Get the column names for a given property as a comma-delimited string of unbracketed names.
        /// </summary>
        /// <param name="persister"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        string GetPropertyColumnNames(AbstractEntityPersister persister, string propertyName)
        {
            var propColumnNames = persister.GetPropertyColumnNames(propertyName);

            if (propColumnNames.Length == 0)
            {
                // this happens when the property is part of the key
                propColumnNames = persister.KeyColumnNames;
            }
            var sb = new StringBuilder();

            foreach (var s in propColumnNames)
            {
                if (sb.Length > 0)
                {
                    sb.Append(',');
                }
                sb.Append(UnBracket(s));
            }
            return(sb.ToString());
        }
예제 #24
0
        /// <summary>
        /// Gets the simple (non-Entity) property that has the given columns
        /// </summary>
        /// <param name="persister"></param>
        /// <param name="columnNames">Comma-delimited column name string</param>
        /// <returns></returns>
        string GetPropertyNameForColumn(AbstractEntityPersister persister, string columnNames)
        {
            var propNames = persister.PropertyNames;
            var propTypes = persister.PropertyTypes;

            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                var propType = propTypes[i];
                if (propType.IsAssociationType)
                {
                    continue;
                }
                var columnArray = persister.GetPropertyColumnNames(i);
                var columns     = CatColumnNames(columnArray);
                if (columns == columnNames)
                {
                    return(propName);
                }
            }
            return(persister.IdentifierPropertyName);
        }
 /// <summary>
 /// Get the column names for a given property as a comma-delimited string of unbracketed names.
 /// For a collection property, the column name is the inverse foreign key (i.e. the column on
 /// the other table that points back to the persister's table)
 /// </summary>
 /// <param name="persister"></param>
 /// <param name="propertyName"></param>
 /// <param name="propType"></param>
 /// <returns></returns>
 string[] GetPropertyColumnNames(AbstractEntityPersister persister, string propertyName, IType propType)
 {
     string[] propColumnNames = null;
     if (propType.IsCollectionType)
     {
         propColumnNames = ((CollectionType)propType).GetReferencedColumns((ISessionFactoryImplementor)this._sessionFactory);
     }
     else
     {
         propColumnNames = persister.GetPropertyColumnNames(propertyName);
     }
     if (propColumnNames == null || propColumnNames.Length == 0)
     {
         // this happens when the property is part of the key
         propColumnNames = persister.KeyColumnNames;
     }
     // HACK for NHibernate formula: when using formula propColumnNames[0] equals null
     if (propColumnNames[0] == null)
     {
         propColumnNames = new string[] { propertyName };
     }
     return(UnBracket(propColumnNames));
 }
        /// <summary>
        /// Make association property metadata for the entity.
        /// Also populates the ForeignKeyMap which is used for related-entity fixup in NHContext.FixupRelationships
        /// </summary>
        /// <param name="containingPersister">Entity Persister containing the property</param>
        /// <param name="propType">Association property</param>
        /// <param name="propName">Name of the property</param>
        /// <param name="dataProperties">Data properties already collected for the containingType.  "isPartOfKey" may be added to a property.</param>
        /// <param name="isKey">Whether the property is part of the key</param>
        /// <returns></returns>
        private Dictionary <string, object> MakeAssociationProperty(AbstractEntityPersister containingPersister, IAssociationType propType, string propName, List <Dictionary <string, object> > dataProperties, bool isKey)
        {
            var nmap = new Dictionary <string, object>();

            nmap.Add("nameOnServer", propName);

            var relatedEntityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType);

            nmap.Add("entityTypeName", relatedEntityType.Name + ":#" + relatedEntityType.Namespace);
            nmap.Add("isScalar", !propType.IsCollectionType);

            // the associationName must be the same at both ends of the association.
            Type containingType = containingPersister.EntityMetamodel.Type;

            string[] columnNames = GetPropertyColumnNames(containingPersister, propName, propType);
            nmap.Add("associationName", GetAssociationName(containingType.Name, relatedEntityType.Name, columnNames));

            string[] fkNames  = null;
            var      joinable = propType.GetAssociatedJoinable((ISessionFactoryImplementor)this._sessionFactory);

            if (propType.IsCollectionType)
            {
                // inverse foreign key
                var collectionPersister = joinable as AbstractCollectionPersister;
                if (collectionPersister != null)
                {
                    if (collectionPersister.IsManyToMany || collectionPersister.IsOneToMany)
                    {
                        // many-to-many relationships do not have a direct connection on the client or in metadata
                        var elementPersister = collectionPersister.ElementPersister as AbstractEntityPersister;
                        if (elementPersister != null)
                        {
                            fkNames = GetPropertyNamesForColumns(elementPersister, columnNames);
                            if (fkNames != null)
                            {
                                nmap.Add("invForeignKeyNamesOnServer", fkNames);
                            }
                        }
                    }
                }
            }
            else
            {
                // Not a collection type - a many-to-one or one-to-one association
                var entityRelationship = containingType.FullName + '.' + propName;
                // Look up the related foreign key name using the column name
                fkNames = GetPropertyNamesForColumns(containingPersister, columnNames);
                if (fkNames != null)
                {
                    if (propType.ForeignKeyDirection == ForeignKeyDirection.ForeignKeyFromParent)
                    {
                        nmap.Add("foreignKeyNamesOnServer", fkNames);
                    }
                    else
                    {
                        nmap.Add("invForeignKeyNamesOnServer", fkNames);
                    }

                    // For many-to-one and one-to-one associations, save the relationship in ForeignKeyMap for re-establishing relationships during save
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", fkNames));
                    if (isKey)
                    {
                        foreach (var fkName in fkNames)
                        {
                            var relatedDataProperty = FindPropertyByName(dataProperties, fkName);
                            if (!relatedDataProperty.ContainsKey("isPartOfKey"))
                            {
                                relatedDataProperty.Add("isPartOfKey", true);
                            }
                        }
                    }
                }
                else if (fkNames == null)
                {
                    nmap.Add("foreignKeyNamesOnServer", columnNames);
                    nmap.Add("ERROR", "Could not find matching fk for property " + entityRelationship);
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", columnNames));
                    throw new ArgumentException("Could not find matching fk for property " + entityRelationship);
                }
            }

            return(nmap);
        }
예제 #27
0
 public abstract string GetAuditNoteForComponentProperty(AbstractEntityPersister persister, ComponentType componentType, int propertyIndexToAudit);
예제 #28
0
 public CompositeEntityBatchFetcher(AbstractEntityPersister persister)
 {
     // Embedded id
     _parameter = Expression.Parameter(typeof(TEntity));
 }
예제 #29
0
        /// <summary>
        /// Make association property metadata for the entity.
        /// Also populates the ForeignKeyMap which is used for related-entity fixup in NHContext.FixupRelationships
        /// </summary>
        /// <param name="containingPersister">Entity Persister containing the property</param>
        /// <param name="propType">Association property</param>
        /// <param name="propName">Name of the property</param>
        /// <param name="dataProperties">Data properties already collected for the containingType.  "isPartOfKey" may be added to a property.</param>
        /// <param name="isKey">Whether the property is part of the key</param>
        /// <returns></returns>
        private Dictionary <string, object> MakeAssociationProperty(AbstractEntityPersister containingPersister, IAssociationType propType, string propName, List <Dictionary <string, object> > dataProperties, bool isKey)
        {
            var nmap = new Dictionary <string, object>();

            nmap.Add("nameOnServer", propName);

            var relatedEntityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType);

            nmap.Add("entityTypeName", relatedEntityType.Name + ":#" + relatedEntityType.Namespace);
            nmap.Add("isScalar", !propType.IsCollectionType);

            // the associationName must be the same at both ends of the association.
            Type containingType = containingPersister.EntityMetamodel.Type;

            string[] columnNames = GetPropertyColumnNames(containingPersister, propName, propType);
            nmap.Add("associationName", GetAssociationName(containingType.Name, relatedEntityType.Name, columnNames));

            var propertyIndex = containingPersister.PropertyNames.ToList().IndexOf(propName);
            var cascadeStyle  = containingPersister.PropertyCascadeStyles[propertyIndex];

            nmap.Add("hasOrphanDelete", cascadeStyle.HasOrphanDelete);


            string[] fkNames             = null;
            var      joinable            = propType.GetAssociatedJoinable((ISessionFactoryImplementor)this._sessionFactory);
            var      memberConfiguration = GetMemberConfiguration(containingType, propName);

            if (!string.IsNullOrEmpty(memberConfiguration.SerializedName))
            {
                nmap.Add("name", memberConfiguration.SerializedName);
            }

            if (propType.IsCollectionType)
            {
                // inverse foreign key
                var collectionPersister = joinable as AbstractCollectionPersister;
                if (collectionPersister != null)
                {
                    // many-to-many relationships do not have a direct connection on the client or in metadata
                    var elementPersister = collectionPersister.ElementPersister as AbstractEntityPersister;
                    if (elementPersister != null)
                    {
                        fkNames = GetPropertyNamesForColumns(elementPersister, columnNames);
                        if (fkNames != null)
                        {
                            nmap.Add("invForeignKeyNamesOnServer", fkNames);
                        }
                    }
                }
            }
            else
            {
                // Not a collection type - a many-to-one or one-to-one association
                var entityRelationship = containingType.FullName + '.' + propName;
                // Look up the related foreign key name using the column name
                fkNames = GetPropertyNamesForColumns(containingPersister, columnNames);

                // TODO: support FK with multiple columns
                if (fkNames == null && columnNames.Length == 1) //try to find the column for the relation if is not specified in class
                {
                    var pType = containingPersister.GetPropertyType(propName);
                    var index = containingPersister.PropertyNames
                                .Select((val, i) => new { Index = i, Value = val })
                                .Where(o => o.Value == propName)
                                .Select(o => o.Index)
                                .First();
                    var isNullable       = containingPersister.PropertyNullability[index];
                    var convertedColumns = new List <string>();
                    foreach (var columnName in columnNames)
                    {
                        // TODO: convert columnName to c# name
                        var synProp = new NHSyntheticProperty
                        {
                            Name           = columnName,
                            FkPropertyName = propName,
                            FkType         = pType,
                            IsNullable     = isNullable
                        };
                        convertedColumns.Add(columnName);

                        var relatedType = _sessionFactory.GetClassMetadata(synProp.FkType.Name);
                        if (relatedType == null)
                        {
                            throw new ArgumentException("Could not find related entity of type " + synProp.FkType.Name);
                        }
                        synProp.PkType         = relatedType.IdentifierType;
                        synProp.PkPropertyName = relatedType.IdentifierPropertyName;

                        if (!_syntheticProperties.ContainsKey(containingType))
                        {
                            _syntheticProperties.Add(containingType, new List <NHSyntheticProperty>());
                        }
                        _syntheticProperties[containingType].Add(synProp);

                        //Create synthetic property as unmapped
                        var dmap = MakeDataProperty(memberConfiguration, columnName, relatedType.IdentifierType, synProp.IsNullable, false, false);
                        dmap["isUnmapped"] = true;
                        dataProperties.Add(dmap);
                    }
                    fkNames = convertedColumns.ToArray();
                }


                if (fkNames != null)
                {
                    if (propType.ForeignKeyDirection == ForeignKeyDirection.ForeignKeyFromParent)
                    {
                        nmap.Add("foreignKeyNamesOnServer", fkNames);
                    }
                    else
                    {
                        nmap.Add("invForeignKeyNamesOnServer", fkNames);
                    }

                    // For many-to-one and one-to-one associations, save the relationship in ForeignKeyMap for re-establishing relationships during save
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", fkNames));
                    if (isKey)
                    {
                        foreach (var fkName in fkNames)
                        {
                            var relatedDataProperty = FindPropertyByName(dataProperties, fkName);
                            if (!relatedDataProperty.ContainsKey("isPartOfKey"))
                            {
                                relatedDataProperty.Add("isPartOfKey", true);
                            }
                        }
                    }
                }
                else if (fkNames == null)
                {
                    nmap.Add("foreignKeyNamesOnServer", columnNames);
                    nmap.Add("ERROR", "Could not find matching fk for property " + entityRelationship);
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", columnNames));
                    throw new ArgumentException("Could not find matching fk for property " + entityRelationship);
                }
            }

            return(nmap);
        }
        /// <summary>
        /// Gets the properties matching the given columns.  May be a component, but will not be an association.
        /// </summary>
        /// <param name="persister"></param>
        /// <param name="columnNames">Array of column names</param>
        /// <returns></returns>
        static string[] GetPropertyNamesForColumns(AbstractEntityPersister persister, string[] columnNames)
        {
            var propNames = persister.PropertyNames;
            var propTypes = persister.PropertyTypes;

            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                var propType = propTypes[i];
                if (propType.IsAssociationType)
                {
                    continue;
                }
                var columnArray = persister.GetPropertyColumnNames(i);
                // HACK for NHibernate formula: when using formula GetPropertyColumnNames(i) returns an array with the first element null
                if (columnArray[0] == null)
                {
                    continue;
                }
                if (NamesEqual(columnArray, columnNames))
                {
                    return new string[] { propName }
                }
                ;
            }

            // If we got here, maybe the property is the identifier
            var keyColumnArray = persister.KeyColumnNames;

            if (NamesEqual(keyColumnArray, columnNames))
            {
                if (persister.IdentifierPropertyName != null)
                {
                    return(new string[] { persister.IdentifierPropertyName });
                }
                if (persister.IdentifierType.IsComponentType)
                {
                    var compType = (ComponentType)persister.IdentifierType;
                    return(compType.PropertyNames);
                }
            }

            if (columnNames.Length > 1)
            {
                // go one-by-one through columnNames, trying to find a matching property.
                // TODO: maybe this should split columnNames into all possible combinations of ordered subsets, and try those
                var propList = new List <string>();
                var prop     = new string[1];
                for (int i = 0; i < columnNames.Length; i++)
                {
                    prop[0] = columnNames[i];
                    var names = GetPropertyNamesForColumns(persister, prop);  // recursive call
                    if (names != null)
                    {
                        propList.AddRange(names);
                    }
                }
                if (propList.Count > 0)
                {
                    return(propList.ToArray());
                }
            }
            return(null);
        }