private void VisitAssign(Expression leftNode, Expression rightNode)
            {
                // Insert and Update statements have assign expressions, where the left side is a parameter and its name
                // represents the property path to be assigned
                if (!(leftNode is ParameterExpression parameterExpression) ||
                    !(rightNode is ConstantExpression constantExpression))
                {
                    return;
                }

                var entityName = _sessionFactory.TryGetGuessEntityName(_targetType);

                if (entityName == null)
                {
                    return;
                }

                var persister = _sessionFactory.GetEntityPersister(entityName);

                ConstantExpressions[constantExpression] = persister.EntityMetamodel.GetPropertyType(parameterExpression.Name);
            }
        private IClassMetadata GetMetaData(System.Type type)
        {
            if (LinqUtil.IsAnonymousType(type))
            {
                return(null);
            }

            string entityName = _sessionFactory.TryGetGuessEntityName(type);

            if (!String.IsNullOrEmpty(entityName) && _metaData.ContainsKey(entityName))
            {
                return(_metaData[entityName]);
            }

            if (_proxyTypes.ContainsKey(type))
            {
                return(_metaData[_proxyTypes[type]]);
            }

            return(null);
        }
		private static bool TryGetEntityPersister(
			System.Type convertedType,
			ISessionFactoryImplementor sessionFactory,
			out IEntityPersister persister)
		{
			if (convertedType == null)
			{
				persister = null;
				return false;
			}

			var entityName = sessionFactory.TryGetGuessEntityName(convertedType);
			if (entityName == null)
			{
				persister = null;
				return false;
			}

			persister = sessionFactory.GetEntityPersister(entityName);
			return true;
		}
        /// <summary>
        /// This translation operation is called when a shard-aware HQL query is to be generated for
        /// a shard that will execute the query. It transforms the shard-unaware query plan
        /// that may contain aggregations and paging instructions that will not work as expected
        /// when query results are to be aggregated from multiple shards.
        /// </summary>
        /// <param name="sessionFactory"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public IASTNode Translate(ISessionFactoryImplementor sessionFactory, bool filter)
        {
            var root = this.UnshardedQueryExpression.Translate(sessionFactory, filter);

            var entityName = sessionFactory.TryGetGuessEntityName(this.Type);

            if (entityName == null)
            {
                if (this.unshardedQueryExpressionPlan.ReturnMetadata.ReturnTypes[0] is EntityType rootEntityType)
                {
                    entityName = rootEntityType.GetAssociatedEntityName(sessionFactory);
                }
            }

            var rootClassMetadata = entityName != null
                        ? sessionFactory.GetClassMetadata(entityName)
                        : null;

            var hqlGenerator = new ShardedHqlGenerator(root, rootClassMetadata, this.parameterValuesByName, this.exitOperationBuilder);

            return(hqlGenerator.ShardedHql);
        }