/// <summary> /// Check sub elements-nullability. Returns property path that break /// nullability or null if none /// </summary> /// <param name="propertyType">type to check </param> /// <param name="value">value to check </param> /// <returns> property path </returns> private string CheckSubElementsNullability(IType propertyType, object value) { //for non null args, check for components and elements containing components if (propertyType.IsComponentType) { return(CheckComponentNullability(value, (IAbstractComponentType)propertyType)); } else if (propertyType.IsCollectionType) { //persistent collections may have components CollectionType collectionType = (CollectionType)propertyType; IType collectionElementType = collectionType.GetElementType(session.Factory); if (collectionElementType.IsComponentType) { //check for all components values in the collection IAbstractComponentType componentType = (IAbstractComponentType)collectionElementType; IEnumerable ec = CascadingAction.GetLoadedElementsIterator(session, collectionType, value); foreach (object compValue in ec) { if (compValue != null) { return(CheckComponentNullability(compValue, componentType)); } } } } return(null); }
private ICriteriaInfoProvider GetPathInfo(string path) { StringTokenizer tokens = new StringTokenizer(path, ".", false); string componentPath = string.Empty; // start with the 'rootProvider' ICriteriaInfoProvider provider; if (nameCriteriaInfoMap.TryGetValue(rootEntityName, out provider) == false) { throw new ArgumentException("Could not find ICriteriaInfoProvider for: " + path); } foreach (string token in tokens) { componentPath += token; logger.DebugFormat("searching for {0}", componentPath); IType type = provider.GetType(componentPath); if (type.IsAssociationType) { // CollectionTypes are always also AssociationTypes - but there's not always an associated entity... IAssociationType atype = (IAssociationType)type; CollectionType ctype = type.IsCollectionType ? (CollectionType)type : null; IType elementType = (ctype != null) ? ctype.GetElementType(sessionFactory) : null; // is the association a collection of components or value-types? (i.e a colloction of valued types?) if (ctype != null && elementType.IsComponentType) { provider = new ComponentCollectionCriteriaInfoProvider(helper.GetCollectionPersister(ctype.Role)); } else if (ctype != null && !elementType.IsEntityType) { provider = new ScalarCollectionCriteriaInfoProvider(helper, ctype.Role); } else { provider = new EntityCriteriaInfoProvider((NHibernate_Persister_Entity.IQueryable)sessionFactory.GetEntityPersister( atype.GetAssociatedEntityName( sessionFactory) )); } componentPath = string.Empty; } else if (type.IsComponentType) { componentPath += '.'; } else { throw new QueryException("not an association: " + componentPath); } } logger.DebugFormat("returning entity name={0} for path={1} class={2}", provider.Name, path, provider.GetType().Name); return(provider); }
protected override Expression VisitMemberAccess(MemberExpression expr) { expr = (MemberExpression)base.VisitMemberAccess(expr); IClassMetadata metaData = GetMetaData(expr.Type); if (metaData != null) { string associationPath = AssociationPathForEntity(expr); return(new EntityExpression(associationPath, expr.Member.Name, expr.Type, metaData, expr.Expression)); } string memberName; IType nhibernateType; EntityExpression parentExpression = GetParentExpression(expr, out memberName, out nhibernateType); if (parentExpression != null) { if (nhibernateType.IsCollectionType) { CollectionType collectionType = (CollectionType)nhibernateType; IType nhElementType = collectionType.GetElementType((ISessionFactoryImplementor)_sessionFactory); System.Type elementType = nhElementType.ReturnedClass; IClassMetadata elementMetaData = GetMetaData(elementType); EntityExpression elementExpression = null; if (elementMetaData != null) { elementExpression = new EntityExpression(null, memberName, elementType, elementMetaData, null); } return(new CollectionAccessExpression(memberName, expr.Type, nhibernateType, parentExpression, elementExpression)); } return(new PropertyAccessExpression(memberName, expr.Type, nhibernateType, parentExpression)); } return(expr); }
/// <summary> Cascade to the collection elements</summary> private void CascadeCollectionElements(object parent, object child, CollectionType collectionType, CascadeStyle style, IType elemType, object anything, bool isCascadeDeleteEnabled) { // we can't cascade to non-embedded elements bool embeddedElements = eventSource.EntityMode != EntityMode.Xml || ((EntityType)collectionType.GetElementType(eventSource.Factory)).IsEmbeddedInXML; bool reallyDoCascade = style.ReallyDoCascade(action) && embeddedElements && child != CollectionType.UnfetchedCollection; if (reallyDoCascade) { log.Info("cascade " + action + " for collection: " + collectionType.Role); foreach (object o in action.GetCascadableChildrenIterator(eventSource, collectionType, child)) { CascadeProperty(parent, o, elemType, style, anything, isCascadeDeleteEnabled); } log.Info("done cascade " + action + " for collection: " + collectionType.Role); } var childAsPersColl = child as IPersistentCollection; bool deleteOrphans = style.HasOrphanDelete && action.DeleteOrphans && elemType.IsEntityType && childAsPersColl != null; //a newly instantiated collection can't have orphans if (deleteOrphans) { // handle orphaned entities!! log.Info("deleting orphans for collection: " + collectionType.Role); // we can do the cast since orphan-delete does not apply to: // 1. newly instantiated collections // 2. arrays (we can't track orphans for detached arrays) string entityName = collectionType.GetAssociatedEntityName(eventSource.Factory); DeleteOrphans(entityName, childAsPersColl); log.Info("done deleting orphans for collection: " + collectionType.Role); } }
/// <summary> /// Gets or sets the data type this collection contains. /// </summary> protected override Type CreateCollectionItemType() => CollectionType?.GetElementType();
/// <summary> /// Given a collection type, determine the Type representing elements /// within instances of that collection. /// </summary> /// <param name="collectionType">The collection type to be checked.</param> /// <returns>The Type of the elements of the collection.</returns> private IType GetElementType(CollectionType collectionType) { return(collectionType.GetElementType(_sfi)); }
protected override Type CreateCollectionItemType() { return(CollectionType.GetElementType()); }
private ICriteriaInfoProvider GetPathInfo(string path, ICriteriaInfoProvider rootProvider) { var tokens = path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); // start with the root ICriteriaInfoProvider provider = rootProvider; if (tokens.Length == 0) { return(provider); } int i = 0; if (entityJoins.TryGetValue(tokens[0], out var entityJoinInfo)) { provider = new EntityCriteriaInfoProvider(entityJoinInfo.Persister); i++; } string componentPath = string.Empty; for (; i < tokens.Length; i++) { componentPath += tokens[i]; logger.Debug("searching for {0}", componentPath); IType type = provider.GetType(componentPath); if (type.IsAssociationType) { // CollectionTypes are always also AssociationTypes - but there's not always an associated entity... IAssociationType atype = (IAssociationType)type; CollectionType ctype = type.IsCollectionType ? (CollectionType)type : null; IType elementType = (ctype != null) ? ctype.GetElementType(sessionFactory) : null; // is the association a collection of components or value-types? (i.e a colloction of valued types?) if (ctype != null && elementType.IsComponentType) { provider = new ComponentCollectionCriteriaInfoProvider(helper.GetCollectionPersister(ctype.Role)); } else if (ctype != null && !elementType.IsEntityType) { provider = new ScalarCollectionCriteriaInfoProvider(helper, ctype.Role); } else { provider = new EntityCriteriaInfoProvider( GetQueryablePersister(atype.GetAssociatedEntityName(sessionFactory))); } componentPath = string.Empty; } else if (type.IsComponentType) { componentPath += '.'; } else { throw new QueryException("not an association: " + componentPath); } } logger.Debug("returning entity name={0} for path={1} class={2}", provider.Name, path, provider.GetType().Name); return(provider); }