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

📄 abstractentitypersister.cs

📁 NHibernate NET开发者所需的
💻 CS
📖 第 1 页 / 共 5 页
字号:
					for (int j = 0; j < lazyPropertyNames.Length; j++)
					{
						object propValue = lazyPropertyTypes[j].NullSafeGet(rs, lazyPropertyColumnAliases[j], session, entity);
						if (InitializeLazyProperty(fieldName, entity, session, snapshot, j, propValue))
						{
							result = propValue;
						}
					}
				}
				finally
				{
					session.Batcher.CloseCommand(ps, rs);
				}

				log.Debug("done initializing lazy properties");

				return result;
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, sqle, "could not initialize lazy properties: " + MessageHelper.InfoString(this, id, Factory), SQLLazySelectString);
			}
		}

		private object InitializeLazyPropertiesFromCache(string fieldName, object entity, ISessionImplementor session, EntityEntry entry, CacheEntry cacheEntry)
		{
			log.Debug("initializing lazy properties from second-level cache");

			object result = null;
			object[] disassembledValues = cacheEntry.DisassembledState;
			object[] snapshot = entry.LoadedState;
			for (int j = 0; j < lazyPropertyNames.Length; j++)
			{
				object propValue = lazyPropertyTypes[j].Assemble(disassembledValues[lazyPropertyNumbers[j]], session, entity);
				if (InitializeLazyProperty(fieldName, entity, session, snapshot, j, propValue))
				{
					result = propValue;
				}
			}

			log.Debug("done initializing lazy properties");

			return result;
		}

		private bool InitializeLazyProperty(string fieldName, object entity, ISessionImplementor session, object[] snapshot, int j, object propValue)
		{
			SetPropertyValue(entity, lazyPropertyNumbers[j], propValue, session.EntityMode);
			if (snapshot != null)
			{
				// object have been loaded with setReadOnly(true); HHH-2236
				snapshot[lazyPropertyNumbers[j]] = lazyPropertyTypes[j].DeepCopy(propValue, session.EntityMode, factory);
			}
			return fieldName.Equals(lazyPropertyNames[j]);
		}

		public string[] IdentifierAliases
		{
			get { return identifierAliases; }
		}

		public string SelectFragment(string alias, string suffix)
		{
			return IdentifierSelectFragment(alias, suffix) + PropertySelectFragment(alias, suffix, false);
		}

		public string[] GetIdentifierAliases(string suffix)
		{
			// NOTE: this assumes something about how PropertySelectFragment is implemented by the subclass!
			// was toUnqotedAliasStrings( getIdentiferColumnNames() ) before - now tried
			// to remove that unquoting and missing aliases..
			return new Alias(suffix).ToAliasStrings(IdentifierAliases, factory.Dialect);
		}

		public string[] GetPropertyAliases(string suffix, int i)
		{
			// NOTE: this assumes something about how pPropertySelectFragment is implemented by the subclass!
			return new Alias(suffix).ToUnquotedAliasStrings(propertyColumnAliases[i], factory.Dialect);
		}

		public string GetDiscriminatorAlias(string suffix)
		{
			// NOTE: this assumes something about how PropertySelectFragment is implemented by the subclass!
			// was toUnqotedAliasStrings( getdiscriminatorColumnName() ) before - now tried
			// to remove that unquoting and missing aliases..		
			return entityMetamodel.HasSubclasses ? new Alias(suffix).ToAliasString(DiscriminatorAlias, factory.Dialect) : null;
		}

		public virtual string IdentifierSelectFragment(string name, string suffix)
		{
			return new SelectFragment(factory.Dialect)
				.SetSuffix(suffix)
				.AddColumns(name, IdentifierColumnNames, IdentifierAliases)
				.ToSqlStringFragment(false);
		}

		public string PropertySelectFragment(string name, string suffix, bool allProperties)
		{
			SelectFragment select = new SelectFragment(Factory.Dialect)
				.SetSuffix(suffix)
				.SetUsedAliases(IdentifierAliases);

			int[] columnTableNumbers = SubclassColumnTableNumberClosure;
			string[] columnAliases = SubclassColumnAliasClosure;
			string[] columns = SubclassColumnClosure;

			for (int i = 0; i < columns.Length; i++)
			{
				bool selectable = (allProperties || !subclassColumnLazyClosure[i]) &&
					!IsSubclassTableSequentialSelect(columnTableNumbers[i]) &&
					subclassColumnSelectableClosure[i];
				if (selectable)
				{
					string subalias = GenerateTableAlias(name, columnTableNumbers[i]);
					select.AddColumn(subalias, columns[i], columnAliases[i]);
				}
			}

			int[] formulaTableNumbers = SubclassFormulaTableNumberClosure;
			string[] formulaTemplates = SubclassFormulaTemplateClosure;
			string[] formulaAliases = SubclassFormulaAliasClosure;
			for (int i = 0; i < formulaTemplates.Length; i++)
			{
				bool selectable = (allProperties || !subclassFormulaLazyClosure[i]) &&
					!IsSubclassTableSequentialSelect(formulaTableNumbers[i]);
				if (selectable)
				{
					string subalias = GenerateTableAlias(name, formulaTableNumbers[i]);
					select.AddFormula(subalias, formulaTemplates[i], formulaAliases[i]);
				}
			}

			if (entityMetamodel.HasSubclasses)
				AddDiscriminatorToSelect(select, name, suffix);

			if (HasRowId)
				select.AddColumn(name, rowIdName, Loadable.RowIdAlias);

			return select.ToSqlStringFragment();
		}

		public object[] GetDatabaseSnapshot(object id, ISessionImplementor session)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("Getting current persistent state for: " + MessageHelper.InfoString(this, id, Factory));
			}

			try
			{
				IDbCommand st = session.Batcher.PrepareCommand(CommandType.Text, SQLSnapshotSelectString, IdentifierType.SqlTypes(factory));
				IDataReader rs = null;
				try
				{
					IdentifierType.NullSafeSet(st, id, 0, session);
					rs = session.Batcher.ExecuteReader(st);

					if (!rs.Read())
					{
						//if there is no resulting row, return null
						return null;
					}

					//otherwise return the "hydrated" state (ie. associations are not resolved)
					IType[] types = PropertyTypes;
					object[] values = new object[types.Length];
					bool[] includeProperty = PropertyUpdateability;
					for (int i = 0; i < types.Length; i++)
					{
						if (includeProperty[i])
						{
							values[i] = types[i].Hydrate(rs, GetPropertyAliases(string.Empty, i), session, null); //null owner ok??
						}
					}
					return values;
				}
				finally
				{
					session.Batcher.CloseCommand(st, rs);
				}
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, sqle, "could not retrieve snapshot: " + MessageHelper.InfoString(this, id, Factory), SQLSnapshotSelectString);
			}
		}

		/// <summary>
		/// Generate the SQL that selects the version number by id
		/// </summary>
		protected SqlString GenerateSelectVersionString()
		{
			SqlSimpleSelectBuilder builder = new SqlSimpleSelectBuilder(Factory.Dialect, factory)
				.SetTableName(VersionedTableName);

			if (IsVersioned)
				builder.AddColumn(versionColumnName);
			else
				builder.AddColumns(rootTableKeyColumnNames);

			if (Factory.Settings.IsCommentsEnabled)
			{
				builder.SetComment("get version " + EntityName);
			}

			return builder.AddWhereFragment(rootTableKeyColumnNames, IdentifierType, " = ").ToSqlString();
		}

		protected SqlString GenerateInsertGeneratedValuesSelectString()
		{
			return GenerateGeneratedValuesSelectString(PropertyInsertGenerationInclusions);
		}

		protected SqlString GenerateUpdateGeneratedValuesSelectString()
		{
			return GenerateGeneratedValuesSelectString(PropertyUpdateGenerationInclusions);
		}

		private SqlString GenerateGeneratedValuesSelectString(ValueInclusion[] inclusions)
		{
			SqlSelectBuilder select = new SqlSelectBuilder(Factory);

			if (Factory.Settings.IsCommentsEnabled)
			{
				select.SetComment("get generated state " + EntityName);
			}

			string[] aliasedIdColumns = StringHelper.Qualify(RootAlias, IdentifierColumnNames);

			// Here we render the select column list based on the properties defined as being generated.
			// For partial component generation, we currently just re-select the whole component
			// rather than trying to handle the individual generated portions.
			string selectClause = ConcretePropertySelectFragment(RootAlias, inclusions);
			selectClause = selectClause.Substring(2);

			string fromClause = FromTableFragment(RootAlias) + FromJoinFragment(RootAlias, true, false);

			SqlString whereClause = new SqlStringBuilder()
				.Add(StringHelper.Join(new SqlString("=", Parameter.Placeholder, " and "), aliasedIdColumns))
				.Add("=").AddParameter()
				.Add(WhereJoinFragment(RootAlias, true, false))
				.ToSqlString();

			return select.SetSelectClause(selectClause)
				.SetFromClause(fromClause)
				.SetOuterJoins(SqlString.Empty, SqlString.Empty)
				.SetWhereClause(whereClause)
				.ToSqlString();
		}

		protected string ConcretePropertySelectFragment(string alias, ValueInclusion[] inclusions)
		{
			return ConcretePropertySelectFragment(alias, new NoneInclusionChecker(inclusions));
		}

		protected string ConcretePropertySelectFragment(string alias, bool[] includeProperty)
		{
			return ConcretePropertySelectFragment(alias, new FullInclusionChecker(includeProperty));
		}

		protected string ConcretePropertySelectFragment(string alias, IInclusionChecker inclusionChecker)
		{
			int propertyCount = PropertyNames.Length;
			int[] propertyTableNumbers = PropertyTableNumbersInSelect;
			SelectFragment frag = new SelectFragment(Factory.Dialect);
			for (int i = 0; i < propertyCount; i++)
			{
				if (inclusionChecker.IncludeProperty(i))
				{
					frag.AddColumns(GenerateTableAlias(alias, propertyTableNumbers[i]), propertyColumnNames[i], propertyColumnAliases[i]);
					frag.AddFormulas(GenerateTableAlias(alias, propertyTableNumbers[i]), propertyColumnFormulaTemplates[i], propertyColumnAliases[i]);
				}
			}
			return frag.ToFragmentString();
		}


		protected virtual SqlString GenerateSnapshotSelectString()
		{
			//TODO: should we use SELECT .. FOR UPDATE?

			SqlSelectBuilder select = new SqlSelectBuilder(Factory);

			if (Factory.Settings.IsCommentsEnabled)
			{
				select.SetComment("get current state " + EntityName);
			}

			string[] aliasedIdColumns = StringHelper.Qualify(RootAlias, IdentifierColumnNames);
			string selectClause = StringHelper.Join(StringHelper.CommaSpace, aliasedIdColumns)
														+ ConcretePropertySelectFragment(RootAlias, PropertyUpdateability);

			SqlString fromClause = new SqlString(FromTableFragment(RootAlias)) +
														 FromJoinFragment(RootAlias, true, false);

			SqlString joiner = new SqlString("=", Parameter.Placeholder, " and ");
			SqlStringBuilder whereClauseBuilder = new SqlStringBuilder()
				.Add(StringHelper.Join(joiner, aliasedIdColumns))
				.Add("=")
				.AddParameter()
				.Add(WhereJoinFragment(RootAlias, true, false));

			// H3.2 the Snapshot is what we found in DB without take care on version
			//if (IsVersioned)
			//{
			//  whereClauseBuilder.Add(" and ")
			//    .Add(VersionColumnName)
			//    .Add("=")
			//    .AddParameter();
			//}

			return select.SetSelectClause(selectClause)
				.SetFromClause(fromClause)
				.SetOuterJoins(SqlString.Empty, SqlString.Empty)
				.SetWhereClause(whereClauseBuilder.ToSqlString())
				.ToSqlString();
		}

		public object ForceVersionIncrement(object id, object currentVersion, ISessionImplementor session)
		{
			if (!IsVersioned)
				throw new AssertionFailure("cannot force version increment on non-versioned entity");

			if (IsVersionPropertyGenerated)
			{
				// the difficulty here is exactly what do we update in order to
				// force the version to be incremented in the db...
				throw new HibernateException("LockMode.Force is currently not supported for generated version properties");
			}

			object nextVersion = VersionType.Next(currentVersion, session);
			if (log.IsDebugEnabled)
			{
				log.Debug("Forcing version increment [" +
					MessageHelper.InfoString(this, id, Factory) + "; " +
					VersionType.ToLoggableString(currentVersion, Factory) + " -> " +
					VersionType.ToLoggableString(nextVersion, Factory) + "]");
			}

			IExpectation expectation = Expectations.AppropriateExpectation(updateResultCheckStyles[0]);
			// todo : cache this sql...
			SqlCommandInfo versionIncrementCommand = GenerateVersionIncrementUpdateString();
			try
			{
				IDbCommand st = session.Batcher.PrepareCommand(versionIncrementCommand.CommandType, versionIncrementCommand.Text, versionIncrementCommand.ParameterTypes);
				try
				{
					VersionType.NullSafeSet(st, nextVersion, 0, session);
					IdentifierType.NullSafeSet(st, id, 1, session);
					VersionType.NullSafeSet(st, currentVersion, 1 + IdentifierColumnSpan, session);
					Check(session.Batcher.ExecuteNonQuery(st), id, 0, expectation, st);
				}
				finally
				{
					session.Batcher.CloseCommand(st, null);
				}
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, sqle,
																				 "could not retrieve version: " + MessageHelper.InfoString(this, id, Factory),
																				 VersionSelectString);
			}
			return nextVersion;
		}

		private SqlCommandInfo GenerateVersionIncrementUpdateString()
		{
			SqlUpdateBuilder update = new SqlUpdateBuilder(Factory.Dialect, Factory);
			update.SetTableName(GetTableName(0));
			if (Factory.Settings.IsCommentsEnabled)
			{
				update.SetComment("forced version increment");
			}
			update.AddColumn(VersionColumnName, VersionType);
			update.SetIdentityColumn(IdentifierColumnNames, IdentifierType);
			update.SetVersionColumn(new string[] { VersionColumnName }, VersionType);
			return update.ToSqlCommandInfo();
		}

		/// <summary>
		/// Retrieve the version number
		/// </summary>
		public object GetCurrentVersion(object id, ISessionImplementor session)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("Getting version: " + MessageHelper.InfoString(this, id, Factory));
			}

			try
			{
				IDbCommand st = session.Batcher.PrepareQueryCommand(CommandType.Text, VersionSelectString, IdentifierType.SqlTypes(Factory));
				IDataReader rs = null;
				try
				{
					IdentifierType.NullSafeSet(st, id, 0, session);
					rs = session.Batcher.ExecuteReader(st);
					if (!rs.Read())
					{
						return null;
					}
					if (!IsVersioned)
					{
						return this;
					}
					return VersionType.NullSafeGet(rs, VersionColumnName, session, null);
				}
				finally
				{
					session.Batcher.CloseCommand(st, rs);
				}
			}
			catch (DbException sqle)
			{
				throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, sqle,
																				 "could not retrieve version: " + MessageHelper.InfoString(this, id, Factory),

⌨️ 快捷键说明

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