customloader.cs

来自「NHibernate NET开发者所需的」· CS 代码 · 共 579 行 · 第 1/2 页

CS
579
字号
using System;
using System.Collections;
using System.Data;
using Iesi.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Hql;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Transform;
using NHibernate.Type;
using NHibernate.Util;

namespace NHibernate.Loader.Custom
{
	public class CustomLoader : Loader
	{
		// Currently *not* cachable if autodiscover types is in effect (e.g. "select * ...")

		private readonly SqlString sql;
		private readonly ISet<string> querySpaces = new HashedSet<string>();
		private readonly IDictionary namedParameterBindPoints;

		private readonly IQueryable[] entityPersisters;
		private readonly int[] entityOwners;
		private readonly IEntityAliases[] entityAliases;

		private readonly IQueryableCollection[] collectionPersisters;
		private readonly int[] collectionOwners;
		private readonly ICollectionAliases[] collectionAliases;

		private LockMode[] lockModes;
		private readonly ResultRowProcessor rowProcessor;

		private IType[] resultTypes;
		private string[] transformerAliases;

		public CustomLoader(
			ICustomQuery customQuery,
			ISessionFactoryImplementor factory)
			: base(factory)
		{
			this.sql = customQuery.SQL;
			this.querySpaces.AddAll(customQuery.QuerySpaces);
			this.namedParameterBindPoints = customQuery.NamedParameterBindPoints;

			IList entityPersisters = new ArrayList();
			IList entityOwners = new ArrayList();
			IList entityAliases = new ArrayList();

			IList collectionPersisters = new ArrayList();
			IList collectionOwners = new ArrayList();
			IList collectionAliases = new ArrayList();

			IList lockModes = new ArrayList();
			IList resultColumnProcessors = new ArrayList();
			IList nonScalarReturnList = new ArrayList();
			IList resultTypes = new ArrayList();
			IList specifiedAliases = new ArrayList();

			int returnableCounter = 0;
			bool hasScalars = false;

			foreach (IReturn rtn in customQuery.CustomQueryReturns)
			{
				if (rtn is ScalarReturn)
				{
					ScalarReturn scalarRtn = (ScalarReturn) rtn;
					resultTypes.Add(scalarRtn.Type);
					specifiedAliases.Add(scalarRtn.ColumnAlias);
					resultColumnProcessors.Add(
						new ScalarResultColumnProcessor(
							scalarRtn.ColumnAlias,
							scalarRtn.Type
							)
						);
					hasScalars = true;
				}
				else if (rtn is RootReturn)
				{
					RootReturn rootRtn = (RootReturn) rtn;
					IQueryable persister = (IQueryable) factory.GetEntityPersister(rootRtn.EntityName);
					entityPersisters.Add(persister);
					lockModes.Add(rootRtn.LockMode);
					resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
					nonScalarReturnList.Add(rtn);
					entityOwners.Add(-1);
					resultTypes.Add(persister.Type);
					specifiedAliases.Add(rootRtn.Alias);
					entityAliases.Add(rootRtn.EntityAliases);
					querySpaces.AddAll(persister.QuerySpaces);
				}
				else if (rtn is CollectionReturn)
				{
					CollectionReturn collRtn = (CollectionReturn) rtn;
					String role = collRtn.OwnerEntityName + "." + collRtn.OwnerProperty;
					IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
					collectionPersisters.Add(persister);
					lockModes.Add(collRtn.LockMode);
					resultColumnProcessors.Add(new NonScalarResultColumnProcessor(returnableCounter++));
					nonScalarReturnList.Add(rtn);
					collectionOwners.Add(-1);
					resultTypes.Add(persister.Type);
					specifiedAliases.Add(collRtn.Alias);
					collectionAliases.Add(collRtn.CollectionAliases);
					// determine if the collection elements are entities...
					IType elementType = persister.ElementType;
					if (elementType.IsEntityType)
					{
						IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
						entityPersisters.Add(elementPersister);
						entityOwners.Add(-1);
						entityAliases.Add(collRtn.ElementEntityAliases);
						querySpaces.AddAll(elementPersister.QuerySpaces);
					}
				}
				else if (rtn is EntityFetchReturn)
				{
					EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn;
					NonScalarReturn ownerDescriptor = fetchRtn.Owner;
					int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
					entityOwners.Add(ownerIndex);
					lockModes.Add(fetchRtn.LockMode);
					IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
					EntityType fetchedType = (EntityType) ownerPersister.GetPropertyType(fetchRtn.OwnerProperty);
					string entityName = fetchedType.GetAssociatedEntityName(Factory);
					IQueryable persister = (IQueryable) factory.GetEntityPersister(entityName);
					entityPersisters.Add(persister);
					nonScalarReturnList.Add(rtn);
					specifiedAliases.Add(fetchRtn.Alias);
					entityAliases.Add(fetchRtn.EntityAliases);
					querySpaces.AddAll(persister.QuerySpaces);
				}
				else if (rtn is CollectionFetchReturn)
				{
					CollectionFetchReturn fetchRtn = (CollectionFetchReturn) rtn;
					NonScalarReturn ownerDescriptor = fetchRtn.Owner;
					int ownerIndex = nonScalarReturnList.IndexOf(ownerDescriptor);
					collectionOwners.Add(ownerIndex);
					lockModes.Add(fetchRtn.LockMode);
					IQueryable ownerPersister = DetermineAppropriateOwnerPersister(ownerDescriptor);
					String role = ownerPersister.EntityName + '.' + fetchRtn.OwnerProperty;
					IQueryableCollection persister = (IQueryableCollection) factory.GetCollectionPersister(role);
					collectionPersisters.Add(persister);
					nonScalarReturnList.Add(rtn);
					specifiedAliases.Add(fetchRtn.Alias);
					collectionAliases.Add(fetchRtn.CollectionAliases);
					// determine if the collection elements are entities...
					IType elementType = persister.ElementType;
					if (elementType.IsEntityType)
					{
						IQueryable elementPersister = (IQueryable) ((EntityType) elementType).GetAssociatedJoinable(factory);
						entityPersisters.Add(elementPersister);
						entityOwners.Add(ownerIndex);
						entityAliases.Add(fetchRtn.ElementEntityAliases);
						querySpaces.AddAll(elementPersister.QuerySpaces);
					}
				}
				else
				{
					throw new HibernateException("unexpected custom query return type : " + rtn.GetType().FullName);
				}
			}

			this.entityPersisters = new IQueryable[entityPersisters.Count];
			for (int i = 0; i < entityPersisters.Count; i++)
			{
				this.entityPersisters[i] = (IQueryable) entityPersisters[i];
			}
			this.entityOwners = ArrayHelper.ToIntArray(entityOwners);
			this.entityAliases = new IEntityAliases[entityAliases.Count];
			for (int i = 0; i < entityAliases.Count; i++)
			{
				this.entityAliases[i] = (IEntityAliases) entityAliases[i];
			}

			this.collectionPersisters = new IQueryableCollection[collectionPersisters.Count];
			for (int i = 0; i < collectionPersisters.Count; i++)
			{
				this.collectionPersisters[i] = (IQueryableCollection) collectionPersisters[i];
			}
			this.collectionOwners = ArrayHelper.ToIntArray(collectionOwners);
			this.collectionAliases = new ICollectionAliases[collectionAliases.Count];
			for (int i = 0; i < collectionAliases.Count; i++)
			{
				this.collectionAliases[i] = (ICollectionAliases) collectionAliases[i];
			}

			this.lockModes = new LockMode[lockModes.Count];
			for (int i = 0; i < lockModes.Count; i++)
			{
				this.lockModes[i] = (LockMode) lockModes[i];
			}

			this.resultTypes = ArrayHelper.ToTypeArray(resultTypes);
			this.transformerAliases = ArrayHelper.ToStringArray(specifiedAliases);

			this.rowProcessor = new ResultRowProcessor(
				hasScalars,
				(ResultColumnProcessor[]) ArrayHelper.ToArray(resultColumnProcessors, typeof(ResultColumnProcessor))
				);
		}

		private IQueryable DetermineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor)
		{
			string entityName = null;
			if (ownerDescriptor is RootReturn)
			{
				entityName = ((RootReturn) ownerDescriptor).EntityName;
			}
			else if (ownerDescriptor is CollectionReturn)
			{
				CollectionReturn collRtn = (CollectionReturn) ownerDescriptor;
				string role = collRtn.OwnerEntityName + "." + collRtn.OwnerProperty;
				ICollectionPersister persister = Factory.GetCollectionPersister(role);
				EntityType ownerType = (EntityType) persister.ElementType;
				entityName = ownerType.GetAssociatedEntityName(Factory);
			}
			else if (ownerDescriptor is FetchReturn)
			{
				FetchReturn fetchRtn = (FetchReturn) ownerDescriptor;
				IQueryable persister = DetermineAppropriateOwnerPersister(fetchRtn.Owner);
				IType ownerType = persister.GetPropertyType(fetchRtn.OwnerProperty);
				if (ownerType.IsEntityType)
				{
					entityName = ((EntityType)ownerType).GetAssociatedEntityName(Factory);
				}
				else if (ownerType.IsCollectionType)
				{
					IType ownerCollectionElementType = ((CollectionType) ownerType).GetElementType(Factory);
					if (ownerCollectionElementType.IsEntityType)
					{
						entityName = ((EntityType) ownerCollectionElementType).GetAssociatedEntityName(Factory);
					}
				}
			}

			if (entityName == null)
			{
				throw new HibernateException("Could not determine fetch owner : " + ownerDescriptor);
			}

			return (IQueryable) Factory.GetEntityPersister(entityName);
		}


		protected internal override ILoadable[] EntityPersisters
		{
			get { return entityPersisters; }
			set { throw new NotSupportedException("CustomLoader.set_EntityPersisters"); }
		}

		protected internal override LockMode[] GetLockModes(IDictionary lockModesMap)
		{
			return lockModes;
		}

		protected override ICollectionPersister[] CollectionPersisters
		{
			get { return collectionPersisters; }
		}

		protected override int[] Owners
		{
			get { return entityOwners; }
		}

		protected override int[] CollectionOwners
		{
			get { return collectionOwners; }
		}

		public ISet<string> QuerySpaces
		{
			get { return querySpaces; }
		}

		// TODO
		//protected string QueryIdentifier
		//{
		//	get { return customQuery.SQL; }
		//}

		public IList List(
			ISessionImplementor session,
			QueryParameters queryParameters)
		{
			return List(session, queryParameters, querySpaces, resultTypes);
		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?