⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entitymetamodel.cs

📁 NHibernate NET开发者所需的
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections.Generic;
using Iesi.Collections.Generic;
using log4net;
using NHibernate.Engine;
using NHibernate.Intercept;
using NHibernate.Mapping;
using NHibernate.Type;
using NHibernate.Util;

namespace NHibernate.Tuple.Entity
{
	[Serializable]
	public class EntityMetamodel
	{
		private static readonly ILog log = LogManager.GetLogger(typeof(EntityMetamodel));

		private const int NoVersionIndex = -66;

		private readonly ISessionFactoryImplementor sessionFactory;

		private readonly string name;
		private readonly string rootName;
		private readonly System.Type type;
		private readonly System.Type rootType;
		private readonly string rootTypeAssemblyQualifiedName;

		private readonly EntityType entityType;

		private readonly IdentifierProperty identifierProperty;
		private readonly bool versioned;

		private readonly int propertySpan;
		private readonly int versionPropertyIndex;

		private readonly StandardProperty[] properties;

		#region temporary

		private readonly string[] propertyNames;
		private readonly IType[] propertyTypes;
		private readonly bool[] propertyLaziness;
		private readonly bool[] propertyUpdateability;
		private readonly bool[] nonlazyPropertyUpdateability;
		private readonly bool[] propertyCheckability;
		private readonly bool[] propertyInsertability;
		private readonly ValueInclusion[] insertInclusions;
		private readonly ValueInclusion[] updateInclusions;
		private readonly bool[] propertyNullability;
		private readonly bool[] propertyVersionability;
		private readonly CascadeStyle[] cascadeStyles;

		#endregion

		private readonly IDictionary<string, int?> propertyIndexes = new Dictionary<string, int?>();
		private readonly bool hasCollections;
		private readonly bool hasMutableProperties;
		private readonly bool hasLazyProperties;

		private readonly int[] naturalIdPropertyNumbers;

		private bool lazy;
		private readonly bool hasCascades;
		private readonly bool hasNonIdentifierPropertyNamedId;
		private readonly bool mutable;
		private readonly bool isAbstract;
		private readonly bool selectBeforeUpdate;
		private readonly bool dynamicUpdate;
		private readonly bool dynamicInsert;
		private readonly Versioning.OptimisticLock optimisticLockMode;

		private readonly bool polymorphic;
		private readonly string superclass;
		private readonly System.Type superclassType;

		private readonly bool explicitPolymorphism;
		private readonly bool inherited;
		private readonly bool hasSubclasses;

		private readonly HashedSet<string> subclassEntityNames = new HashedSet<string>();
		private readonly bool hasInsertGeneratedValues;
		private readonly bool hasUpdateGeneratedValues;

		public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
		{
			this.sessionFactory = sessionFactory;


			name = persistentClass.EntityName;
			rootName = persistentClass.RootClazz.EntityName;
			entityType = TypeFactory.ManyToOne(name);
			type = persistentClass.MappedClass;
			rootType = persistentClass.RootClazz.MappedClass;
			rootTypeAssemblyQualifiedName = rootType.AssemblyQualifiedName;

			identifierProperty =
				PropertyFactory.BuildIdentifierProperty(persistentClass, sessionFactory.GetIdentifierGenerator(rootType));

			versioned = persistentClass.IsVersioned;

			bool lazyAvailable = persistentClass.HasPocoRepresentation && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
			bool hasLazy = false;

			propertySpan = persistentClass.PropertyClosureSpan;
			properties = new StandardProperty[propertySpan];
			List<int> naturalIdNumbers = new List<int>();

			#region temporary

			propertyNames = new string[propertySpan];
			propertyTypes = new IType[propertySpan];
			propertyUpdateability = new bool[propertySpan];
			propertyInsertability = new bool[propertySpan];
			insertInclusions = new ValueInclusion[propertySpan];
			updateInclusions = new ValueInclusion[propertySpan];
			nonlazyPropertyUpdateability = new bool[propertySpan];
			propertyCheckability = new bool[propertySpan];
			propertyNullability = new bool[propertySpan];
			propertyVersionability = new bool[propertySpan];
			propertyLaziness = new bool[propertySpan];
			cascadeStyles = new CascadeStyle[propertySpan];

			#endregion


			int i = 0;
			int tempVersionProperty = NoVersionIndex;
			bool foundCascade = false;
			bool foundCollection = false;
			bool foundMutable = false;
			bool foundInsertGeneratedValue = false;
			bool foundUpdateGeneratedValue = false;
			bool foundNonIdentifierPropertyNamedId = false;

			foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
			{
				if (prop == persistentClass.Version)
				{
					tempVersionProperty = i;
					properties[i] = PropertyFactory.BuildVersionProperty(prop, lazyAvailable);
				}
				else
				{
					properties[i] = PropertyFactory.BuildStandardProperty(prop, lazyAvailable);
				}

				if (prop.IsNaturalIdentifier)
				{
					naturalIdNumbers.Add(i);
				}

				if ("id".Equals(prop.Name))
				{
					foundNonIdentifierPropertyNamedId = true;
				}

				#region temporary
				bool lazyProperty = prop.IsLazy && lazyAvailable;
				if (lazyProperty)
					hasLazy = true;
				propertyLaziness[i] = lazyProperty;

				propertyNames[i] = properties[i].Name;
				propertyTypes[i] = properties[i].Type;
				propertyNullability[i] = properties[i].IsNullable;
				propertyUpdateability[i] = properties[i].IsUpdateable;
				propertyInsertability[i] = properties[i].IsInsertable;
				insertInclusions[i] = DetermineInsertValueGenerationType(prop, properties[i]);
				updateInclusions[i] = DetermineUpdateValueGenerationType(prop, properties[i]);
				propertyVersionability[i] = properties[i].IsVersionable;
				nonlazyPropertyUpdateability[i] = properties[i].IsUpdateable && !lazyProperty;
				propertyCheckability[i] = propertyUpdateability[i] ||
				                          (propertyTypes[i].IsAssociationType &&
				                           ((IAssociationType) propertyTypes[i]).IsAlwaysDirtyChecked);

				cascadeStyles[i] = properties[i].CascadeStyle;
				#endregion

				if (properties[i].IsLazy)
				{
					hasLazy = true;
				}

				if (properties[i].CascadeStyle != CascadeStyle.None)
				{
					foundCascade = true;
				}

				if (IndicatesCollection(properties[i].Type))
				{
					foundCollection = true;
				}

				if (propertyTypes[i].IsMutable && propertyCheckability[i])
				{
					foundMutable = true;
				}

				if (insertInclusions[i] != ValueInclusion.None)
				{
					foundInsertGeneratedValue = true;
				}

				if (updateInclusions[i] != ValueInclusion.None)
				{
					foundUpdateGeneratedValue = true;
				}

				MapPropertyToIndex(prop, i);
				i++;
			}

			if (naturalIdNumbers.Count == 0)
				naturalIdPropertyNumbers = null;
			else
				naturalIdPropertyNumbers = naturalIdNumbers.ToArray();

			hasCascades = foundCascade;
			hasInsertGeneratedValues = foundInsertGeneratedValue;
			hasUpdateGeneratedValues = foundUpdateGeneratedValue;
			hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

			versionPropertyIndex = tempVersionProperty;
			hasLazyProperties = hasLazy;
			if (hasLazyProperties) log.Info("lazy property fetching available for: " + name);

			lazy = persistentClass.IsLazy && 
				(!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
			mutable = persistentClass.IsMutable;

			if (!persistentClass.IsAbstract.HasValue)
			{
				// legacy behavior (with no abstract attribute specified)
				isAbstract = persistentClass.HasPocoRepresentation &&
				             ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
			}
			else
			{
				isAbstract = persistentClass.IsAbstract.Value;
				if (!isAbstract && persistentClass.HasPocoRepresentation &&
				    ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
				{
					log.Warn("entity [" + type.FullName +
					         "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
				}
			}
			selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
			dynamicUpdate = persistentClass.DynamicUpdate;
			dynamicInsert = persistentClass.DynamicInsert;

			polymorphic = persistentClass.IsPolymorphic;
			explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
			inherited = persistentClass.IsInherited;
			superclass = inherited ? persistentClass.Superclass.EntityName : null;
			superclassType = inherited ?
			                           	persistentClass.Superclass.MappedClass :
			                           	                                       	null;
			hasSubclasses = persistentClass.HasSubclasses;

			optimisticLockMode = persistentClass.OptimisticLockMode;
			if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
			{
				throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
			}

			hasCollections = foundCollection;
			hasMutableProperties = foundMutable;

			foreach (Subclass obj in persistentClass.SubclassIterator)
			{
				subclassEntityNames.Add(obj.EntityName);
			}
			subclassEntityNames.Add(name);

			tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this);
		}

		private ValueInclusion DetermineInsertValueGenerationType(Mapping.Property mappingProperty, StandardProperty runtimeProperty)
		{
			if (runtimeProperty.IsInsertGenerated)
			{
				return ValueInclusion.Full;
			}
			else if (mappingProperty.Value is Mapping.Component)
			{
				if (HasPartialInsertComponentGeneration((Mapping.Component)mappingProperty.Value))
				{
					return ValueInclusion.Partial;
				}
			}
			return ValueInclusion.None;
		}

		private bool HasPartialInsertComponentGeneration(Mapping.Component component)
		{
			foreach (Mapping.Property prop in component.PropertyIterator)
			{
				if (prop.Generation == PropertyGeneration.Always || prop.Generation == PropertyGeneration.Insert)
				{
					return true;
				}
				else if (prop.Value is Mapping.Component)
				{
					if (HasPartialInsertComponentGeneration((Mapping.Component)prop.Value))
					{
						return true;
					}
				}
			}
			return false;
		}

		private ValueInclusion DetermineUpdateValueGenerationType(Mapping.Property mappingProperty, StandardProperty runtimeProperty)
		{
			if (runtimeProperty.IsUpdateGenerated)
			{
				return ValueInclusion.Full;
			}
			else if (mappingProperty.Value is Mapping.Component)
			{
				if (HasPartialUpdateComponentGeneration((Mapping.Component)mappingProperty.Value))
				{
					return ValueInclusion.Partial;
				}
			}
			return ValueInclusion.None;
		}

		private bool HasPartialUpdateComponentGeneration(Mapping.Component component)
		{
			foreach (Mapping.Property prop in component.PropertyIterator)
			{
				if (prop.Generation == PropertyGeneration.Always)
				{
					return true;
				}
				else if (prop.Value is Mapping.Component)
				{
					if (HasPartialUpdateComponentGeneration((Mapping.Component)prop.Value))

⌨️ 快捷键说明

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