criteriaquerytranslator.cs
来自「NHibernate NET开发者所需的」· CS 代码 · 共 702 行 · 第 1/2 页
CS
702 行
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Iesi.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Criterion;
using NHibernate.Hql.Util;
using NHibernate.Impl;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
namespace NHibernate.Loader.Criteria
{
public class CriteriaQueryTranslator : ICriteriaQuery
{
public static readonly string RootSqlAlias = CriteriaUtil.RootAlias + '_';
private readonly ICriteriaQuery outerQueryTranslator;
private readonly CriteriaImpl rootCriteria;
private readonly string rootEntityName;
private readonly string rootSQLAlias;
private readonly int aliasCount = 0;
private readonly IDictionary<ICriteria, string> criteriaEntityNames = new LinkedHashMap<ICriteria, string>();
private readonly ISet<ICollectionPersister> criteriaCollectionPersisters = new HashedSet<ICollectionPersister>();
private readonly IDictionary<ICriteria, string> criteriaSQLAliasMap = new Dictionary<ICriteria, string>();
private readonly IDictionary<string, ICriteria> aliasCriteriaMap = new Dictionary<string, ICriteria>();
private readonly IDictionary<string, ICriteria> associationPathCriteriaMap = new LinkedHashMap<string, ICriteria>();
private readonly IDictionary<string, JoinType> associationPathJoinTypesMap = new LinkedHashMap<string, JoinType>();
private readonly ISessionFactoryImplementor sessionFactory;
private int indexForAlias = 0;
public CriteriaQueryTranslator(
ISessionFactoryImplementor factory,
CriteriaImpl criteria,
string rootEntityName,
string rootSQLAlias,
ICriteriaQuery outerQuery)
: this(factory, criteria, rootEntityName, rootSQLAlias)
{
outerQueryTranslator = outerQuery;
}
public CriteriaQueryTranslator(
ISessionFactoryImplementor factory,
CriteriaImpl criteria,
string rootEntityName,
string rootSQLAlias)
{
rootCriteria = criteria;
this.rootEntityName = rootEntityName;
sessionFactory = factory;
this.rootSQLAlias = rootSQLAlias;
CreateAliasCriteriaMap();
CreateAssociationPathCriteriaMap();
CreateCriteriaEntityNameMap();
CreateCriteriaCollectionPersisters();
CreateCriteriaSQLAliasMap();
}
public string GenerateSQLAlias()
{
return StringHelper.GenerateAlias(rootSQLAlias, aliasCount);
}
public int GetIndexForAlias()
{
return indexForAlias++;
}
private ICriteria GetAliasedCriteria(string alias)
{
ICriteria result;
aliasCriteriaMap.TryGetValue(alias, out result);
return result;
}
public bool IsJoin(string path)
{
return associationPathCriteriaMap.ContainsKey(path);
}
public JoinType GetJoinType(string path)
{
JoinType result;
if (associationPathJoinTypesMap.TryGetValue(path, out result))
return result;
else
return JoinType.InnerJoin;
}
public ICriteria GetCriteria(string path)
{
ICriteria result;
associationPathCriteriaMap.TryGetValue(path, out result);
return result;
}
public ISet<string> GetQuerySpaces()
{
ISet<string> result = new HashedSet<string>();
foreach (string entityName in criteriaEntityNames.Values)
{
result.AddAll(Factory.GetEntityPersister(entityName).QuerySpaces);
}
foreach (ICollectionPersister collectionPersister in criteriaCollectionPersisters)
{
result.AddAll(collectionPersister.CollectionSpaces);
}
return result;
}
private void CreateAliasCriteriaMap()
{
aliasCriteriaMap[rootCriteria.Alias] = rootCriteria;
foreach (ICriteria subcriteria in rootCriteria.IterateSubcriteria())
{
if (subcriteria.Alias != null)
{
try
{
aliasCriteriaMap.Add(subcriteria.Alias, subcriteria);
}
catch (ArgumentException ae)
{
throw new QueryException("duplicate alias: " + subcriteria.Alias, ae);
}
}
}
}
private void CreateAssociationPathCriteriaMap()
{
foreach (CriteriaImpl.Subcriteria crit in rootCriteria.IterateSubcriteria())
{
string wholeAssociationPath = GetWholeAssociationPath(crit);
try
{
associationPathCriteriaMap.Add(wholeAssociationPath, crit);
}
catch (ArgumentException ae)
{
throw new QueryException("duplicate association path: " + wholeAssociationPath, ae);
}
try
{
associationPathJoinTypesMap.Add(wholeAssociationPath, crit.JoinType);
}
catch (ArgumentException ae)
{
throw new QueryException("duplicate association path: " + wholeAssociationPath, ae);
}
}
}
private string GetWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria)
{
string path = subcriteria.Path;
// some messy, complex stuff here, since createCriteria() can take an
// aliased path, or a path rooted at the creating criteria instance
ICriteria parent = null;
if (path.IndexOf('.') > 0)
{
// if it is a compound path
string testAlias = StringHelper.Root(path);
if (!testAlias.Equals(subcriteria.Alias))
{
// and the qualifier is not the alias of this criteria
// -> check to see if we belong to some criteria other
// than the one that created us
aliasCriteriaMap.TryGetValue(testAlias, out parent);
}
}
if (parent == null)
{
// otherwise assume the parent is the the criteria that created us
parent = subcriteria.Parent;
}
else
{
path = StringHelper.Unroot(path);
}
if (parent.Equals(rootCriteria))
{
// if its the root criteria, we are done
return path;
}
else
{
// otherwise, recurse
return GetWholeAssociationPath((CriteriaImpl.Subcriteria)parent) + '.' + path;
}
}
private void CreateCriteriaEntityNameMap()
{
criteriaEntityNames[rootCriteria] = rootEntityName;
foreach (KeyValuePair<string, ICriteria> me in associationPathCriteriaMap)
{
criteriaEntityNames[me.Value] = GetPathEntityName(me.Key);
}
}
private void CreateCriteriaCollectionPersisters()
{
foreach (KeyValuePair<string, ICriteria> me in associationPathCriteriaMap)
{
IJoinable joinable = GetPathJoinable(me.Key);
if (joinable.IsCollection)
{
criteriaCollectionPersisters.Add((ICollectionPersister)joinable);
}
}
}
private IJoinable GetPathJoinable(string path)
{
IJoinable last = (IJoinable)Factory.GetEntityPersister(rootEntityName);
IPropertyMapping lastEntity = (IPropertyMapping)last;
string componentPath = "";
StringTokenizer tokens = new StringTokenizer(path, ".", false);
foreach (string token in tokens)
{
componentPath += token;
IType type = lastEntity.ToType(componentPath);
if (type.IsAssociationType)
{
IAssociationType atype = (IAssociationType)type;
last = atype.GetAssociatedJoinable(Factory);
lastEntity = (IPropertyMapping)Factory.GetEntityPersister(atype.GetAssociatedEntityName(Factory));
componentPath = "";
}
else if (type.IsComponentType)
{
componentPath += '.';
}
else
{
throw new QueryException("not an association: " + componentPath);
}
}
return last;
}
private string GetPathEntityName(string path)
{
IQueryable persister = (IQueryable)sessionFactory.GetEntityPersister(rootEntityName);
StringTokenizer tokens = new StringTokenizer(path, ".", false);
string componentPath = "";
foreach (string token in tokens)
{
componentPath += token;
IType type = persister.ToType(componentPath);
if (type.IsAssociationType)
{
IAssociationType atype = (IAssociationType)type;
persister = (IQueryable)sessionFactory.GetEntityPersister(atype.GetAssociatedEntityName(sessionFactory));
componentPath = "";
}
else if (type.IsComponentType)
{
componentPath += '.';
}
else
{
throw new QueryException("not an association: " + componentPath);
}
}
return persister.EntityName;
}
public int SQLAliasCount
{
get { return criteriaSQLAliasMap.Count; }
}
private void CreateCriteriaSQLAliasMap()
{
int i = 0;
foreach (KeyValuePair<ICriteria, string> me in criteriaEntityNames)
{
ICriteria crit = me.Key;
string alias = crit.Alias;
if (alias == null)
{
alias = me.Value;
}
criteriaSQLAliasMap[crit] = StringHelper.GenerateAlias(alias, i++);
}
criteriaSQLAliasMap[rootCriteria] = rootSQLAlias;
}
public CriteriaImpl RootCriteria
{
get { return rootCriteria; }
}
public QueryParameters GetQueryParameters()
{
ArrayList values = new ArrayList();
ArrayList types = new ArrayList();
foreach (CriteriaImpl.CriterionEntry ce in rootCriteria.IterateExpressionEntries())
{
TypedValue[] tv = ce.Criterion.GetTypedValues(ce.Criteria, this);
for (int i = 0; i < tv.Length; i++)
{
values.Add(tv[i].Value);
types.Add(tv[i].Type);
}
}
if (rootCriteria.Projection != null)
{
TypedValue[] tv = rootCriteria.Projection.GetTypedValues(rootCriteria.ProjectionCriteria, this);
for (int i = 0; i < tv.Length; i++)
{
values.Add(tv[i].Value);
types.Add(tv[i].Type);
}
}
object[] valueArray = values.ToArray();
IType[] typeArray = (IType[])types.ToArray(typeof(IType));
RowSelection selection = new RowSelection();
selection.FirstRow = rootCriteria.FirstResult;
selection.MaxRows = rootCriteria.MaxResults;
selection.Timeout = rootCriteria.Timeout;
selection.FetchSize = rootCriteria.FetchSize;
IDictionary lockModes = new Hashtable();
foreach (DictionaryEntry me in rootCriteria.LockModes)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?