|
From: <fab...@us...> - 2010-08-02 11:35:15
|
Revision: 5091
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5091&view=rev
Author: fabiomaulo
Date: 2010-08-02 11:35:07 +0000 (Mon, 02 Aug 2010)
Log Message:
-----------
Apply NH-2190 (thanks to Mihai Codrean)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs
trunk/nhibernate/src/NHibernate/Dialect/Sybase11Dialect.cs
trunk/nhibernate/src/NHibernate/Engine/JoinSequence.cs
trunk/nhibernate/src/NHibernate/ICriteria.cs
trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs
trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs
trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs
trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs
trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs
trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs
trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs
trunk/nhibernate/src/NHibernate/Loader/OuterJoinableAssociation.cs
trunk/nhibernate/src/NHibernate/SqlCommand/ANSIJoinFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/InformixJoinFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/JoinFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/OracleJoinFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/QueryJoinFragment.cs
trunk/nhibernate/src/NHibernate/Util/StringHelper.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -129,6 +129,12 @@
return this;
}
+ public DetachedCriteria CreateAlias(string associationPath, string alias, JoinType joinType, ICriterion withClause)
+ {
+ criteria.CreateAlias(associationPath, alias, joinType, withClause);
+ return this;
+ }
+
public DetachedCriteria CreateCriteria(string associationPath, string alias)
{
return new DetachedCriteria(impl, criteria.CreateCriteria(associationPath, alias));
Modified: trunk/nhibernate/src/NHibernate/Dialect/Sybase11Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Sybase11Dialect.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Dialect/Sybase11Dialect.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -69,7 +69,7 @@
}
public override void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on)
+ SqlString on)
{
AddJoin(tableName, alias, fkColumns, pkColumns, joinType);
AddCondition(on);
Modified: trunk/nhibernate/src/NHibernate/Engine/JoinSequence.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/JoinSequence.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Engine/JoinSequence.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -203,7 +203,7 @@
join.LHSColumns,
JoinHelper.GetRHSColumnNames(join.AssociationType, factory),
join.JoinType,
- condition
+ new SqlString(condition)
);
if (includeExtraJoins)
{
Modified: trunk/nhibernate/src/NHibernate/ICriteria.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/ICriteria.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/ICriteria.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -130,6 +130,17 @@
ICriteria CreateAlias(string associationPath, string alias, JoinType joinType);
/// <summary>
+ /// Join an association using the specified join-type, assigning an alias to the joined
+ /// association
+ /// </summary>
+ /// <param name="associationPath"></param>
+ /// <param name="alias"></param>
+ /// <param name="joinType">The type of join to use.</param>
+ /// <param name="withClause"The criteria to be added to the join condition (ON clause)</param>
+ /// <returns>this (for method chaining)</returns>
+ ICriteria CreateAlias(string associationPath, string alias, JoinType joinType, ICriterion withClause);
+
+ /// <summary>
/// Create a new <see cref="ICriteria" />, "rooted" at the associated entity
/// </summary>
/// <param name="associationPath"></param>
@@ -165,6 +176,17 @@
ICriteria CreateCriteria(string associationPath, string alias, JoinType joinType);
/// <summary>
+ /// Create a new <see cref="ICriteria" />, "rooted" at the associated entity,
+ /// assigning the given alias and using the specified join type.
+ /// </summary>
+ /// <param name="associationPath">A dot-separated property path</param>
+ /// <param name="alias">The alias to assign to the joined association (for later reference).</param>
+ /// <param name="joinType">The type of join to use.</param>
+ /// <param name="withClause"The criteria to be added to the join condition (ON clause)</param>
+ /// <returns>The created "sub criteria"</returns>
+ ICriteria CreateCriteria(string associationPath, string alias, JoinType joinType, ICriterion withClause);
+
+ /// <summary>
/// Set a strategy for handling the query results. This determines the
/// "shape" of the query result set.
/// <seealso cref="CriteriaSpecification.RootEntity"/>
Modified: trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -345,6 +345,12 @@
return this;
}
+ public ICriteria CreateAlias(string associationPath, string alias, JoinType joinType, ICriterion withClause)
+ {
+ new Subcriteria(this, this, associationPath, alias, joinType, withClause);
+ return this;
+ }
+
public ICriteria Add(ICriteria criteriaInst, ICriterion expression)
{
criteria.Add(new CriterionEntry(expression, criteriaInst));
@@ -371,6 +377,11 @@
return new Subcriteria(this, this, associationPath, alias, joinType);
}
+ public ICriteria CreateCriteria(string associationPath, string alias, JoinType joinType, ICriterion withClause)
+ {
+ return new Subcriteria(this, this, associationPath, alias, joinType, withClause);
+ }
+
public IFutureValue<T> FutureValue<T>()
{
if (!session.Factory.ConnectionProvider.Driver.SupportsMultipleQueries)
@@ -607,14 +618,16 @@
private readonly string path;
private LockMode lockMode;
private readonly JoinType joinType;
+ private ICriterion withClause;
- internal Subcriteria(CriteriaImpl root, ICriteria parent, string path, string alias, JoinType joinType)
+ internal Subcriteria(CriteriaImpl root, ICriteria parent, string path, string alias, JoinType joinType, ICriterion withClause)
{
this.root = root;
this.parent = parent;
this.alias = alias;
this.path = path;
this.joinType = joinType;
+ this.withClause = withClause;
root.subcriteriaList.Add(this);
@@ -625,9 +638,17 @@
}
}
+ internal Subcriteria(CriteriaImpl root, ICriteria parent, string path, string alias, JoinType joinType)
+ : this(root, parent, path, alias, joinType, null) {}
+
internal Subcriteria(CriteriaImpl root, ICriteria parent, string path, JoinType joinType)
- : this(root, parent, path, null, joinType) {}
+ : this(root, parent, path, null, joinType) { }
+ public ICriterion WithClause
+ {
+ get { return withClause; }
+ }
+
public string Path
{
get { return path; }
@@ -688,6 +709,12 @@
return this;
}
+ public ICriteria CreateAlias(string associationPath, string alias, JoinType joinType, ICriterion withClause)
+ {
+ new Subcriteria(root, this, associationPath, alias, joinType, withClause);
+ return this;
+ }
+
public ICriteria CreateCriteria(string associationPath)
{
return CreateCriteria(associationPath, JoinType.InnerJoin);
@@ -708,6 +735,11 @@
return new Subcriteria(root, this, associationPath, alias, joinType);
}
+ public ICriteria CreateCriteria(string associationPath, string alias, JoinType joinType, ICriterion withClause)
+ {
+ return new Subcriteria(root, this, associationPath, alias, joinType, withClause);
+ }
+
public ICriteria SetCacheable(bool cacheable)
{
root.SetCacheable(cacheable);
Modified: trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -4,6 +4,7 @@
using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
+using NHibernate.Loader.Criteria;
namespace NHibernate.Loader
{
@@ -33,19 +34,27 @@
WalkEntityTree(persister, Alias);
IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations);
allAssociations.Add(
- new OuterJoinableAssociation(persister.EntityType, null, null, alias, JoinType.LeftOuterJoin, Factory,
+ new OuterJoinableAssociation(persister.EntityType, null, null, alias, JoinType.LeftOuterJoin, null, Factory,
new CollectionHelper.EmptyMapClass<string, IFilter>()));
InitPersisters(allAssociations, lockMode);
InitStatementString(whereString, orderByString, lockMode);
}
- protected void InitProjection(SqlString projectionString, SqlString whereString,
- SqlString orderByString, string groupByString, SqlString havingString, LockMode lockMode)
+ protected void InitProjection(CriteriaQueryTranslator translator,
+ IDictionary<string, IFilter> enabledFilters, LockMode lockMode)
{
+ // the order of the calls here is important, as the join clauses can contain parameter bindings
+ SqlString projectionString = translator.GetSelect(enabledFilters);
WalkEntityTree(persister, Alias);
+ SqlString whereString = translator.GetWhereCondition(enabledFilters);
+ SqlString orderByString = translator.GetOrderBy();
+ SqlString groupByString = translator.GetGroupBy();
+ SqlString havingString = translator.GetHavingCondition(enabledFilters);
+
Persisters = new ILoadable[0];
- InitStatementString(projectionString, whereString, orderByString, groupByString, havingString, lockMode);
+ InitStatementString(projectionString, whereString, orderByString, groupByString.ToString(),
+ havingString, lockMode);
}
private void InitStatementString(SqlString condition, SqlString orderBy, LockMode lockMode)
Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -29,7 +29,7 @@
// NH Different behavior : passing enabledFilters instead empty-filter
allAssociations.Add(
- new OuterJoinableAssociation(collectionPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, Factory,
+ new OuterJoinableAssociation(collectionPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory,
enabledFilters));
InitPersisters(allAssociations, LockMode.None);
Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -35,7 +35,7 @@
IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations);
allAssociations.Add(
- new OuterJoinableAssociation(oneToManyPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, Factory,
+ new OuterJoinableAssociation(oneToManyPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory,
new CollectionHelper.EmptyMapClass<string, IFilter>()));
InitPersisters(allAssociations, LockMode.None);
Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -42,9 +42,7 @@
{
resultTypes = translator.ProjectedTypes;
- InitProjection(translator.GetSelect(enabledFilters), translator.GetWhereCondition(enabledFilters),
- translator.GetOrderBy(), translator.GetGroupBy().ToString(),
- translator.GetHavingCondition(enabledFilters), LockMode.None);
+ InitProjection(translator, enabledFilters, LockMode.None);
}
else
{
@@ -175,5 +173,10 @@
return CriteriaQueryTranslator.RootSqlAlias;
// NH: really not used (we are using a different ctor to support SubQueryCriteria)
}
+
+ protected override SqlString GetWithClause(string path)
+ {
+ return translator.GetWithClause(path, EnabledFilters);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -39,6 +39,7 @@
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 IDictionary<string, ICriterion> withClauseMap = new Dictionary<string, ICriterion>();
private readonly ISessionFactoryImplementor sessionFactory;
private int indexForAlias = 0;
@@ -300,6 +301,18 @@
{
throw new QueryException("duplicate association path: " + wholeAssociationPath, ae);
}
+
+ try
+ {
+ if (crit.WithClause != null)
+ {
+ withClauseMap.Add(wholeAssociationPath, crit.WithClause);
+ }
+ }
+ catch (ArgumentException ae)
+ {
+ throw new QueryException("duplicate association path: " + wholeAssociationPath, ae);
+ }
}
}
@@ -685,6 +698,16 @@
return propertyName;
}
+ public SqlString GetWithClause(string path, IDictionary<string, IFilter> enabledFilters)
+ {
+ if (withClauseMap.ContainsKey(path))
+ {
+ ICriterion crit = (ICriterion)withClauseMap[path];
+ return crit == null ? null : crit.ToSqlString(GetCriteria(path), this, enabledFilters);
+ }
+ return null;
+ }
+
#region NH specific
public int GetIndexForAlias()
Modified: trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -130,6 +130,11 @@
}
}
+ protected virtual SqlString GetWithClause(string path)
+ {
+ return SqlString.Empty;
+ }
+
/// <summary>
/// Add on association (one-to-one, many-to-one, or a collection) to a list
/// of associations to be fetched by outerjoin
@@ -142,7 +147,7 @@
string subalias = GenerateTableAlias(associations.Count + 1, path, joinable);
OuterJoinableAssociation assoc =
- new OuterJoinableAssociation(type, alias, aliasedLhsColumns, subalias, joinType, Factory, enabledFilters);
+ new OuterJoinableAssociation(type, alias, aliasedLhsColumns, subalias, joinType, GetWithClause(path), Factory, enabledFilters);
assoc.ValidateJoin(path);
associations.Add(assoc);
Modified: trunk/nhibernate/src/NHibernate/Loader/OuterJoinableAssociation.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/OuterJoinableAssociation.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Loader/OuterJoinableAssociation.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -5,6 +5,7 @@
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Type;
+using NHibernate.Util;
namespace NHibernate.Loader
{
@@ -17,11 +18,11 @@
private readonly string rhsAlias;
private readonly string[] rhsColumns;
private readonly JoinType joinType;
- private readonly string on;
+ private readonly SqlString on;
private readonly IDictionary<string, IFilter> enabledFilters;
public OuterJoinableAssociation(IAssociationType joinableType, String lhsAlias, String[] lhsColumns, String rhsAlias,
- JoinType joinType, ISessionFactoryImplementor factory,
+ JoinType joinType, SqlString withClause, ISessionFactoryImplementor factory,
IDictionary<string, IFilter> enabledFilters)
{
this.joinableType = joinableType;
@@ -31,7 +32,9 @@
this.joinType = joinType;
joinable = joinableType.GetAssociatedJoinable(factory);
rhsColumns = JoinHelper.GetRHSColumnNames(joinableType, factory);
- on = joinableType.GetOnCondition(rhsAlias, factory, enabledFilters);
+ on = new SqlString(joinableType.GetOnCondition(rhsAlias, factory, enabledFilters));
+ if (StringHelper.IsNotEmpty(withClause))
+ on = on.Append(" and ( ").Append(withClause).Append(" )");
this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
}
@@ -146,9 +149,10 @@
public void AddManyToManyJoin(JoinFragment outerjoin, IQueryableCollection collection)
{
string manyToManyFilter = collection.GetManyToManyFilterFragment(rhsAlias, enabledFilters);
- string condition = string.Empty.Equals(manyToManyFilter)
+ SqlString condition = string.Empty.Equals(manyToManyFilter)
? on
- : string.Empty.Equals(on) ? manyToManyFilter : on + " and " + manyToManyFilter;
+ : StringHelper.IsEmpty(on) ? new SqlString(manyToManyFilter) :
+ on.Append(" and ").Append(manyToManyFilter);
outerjoin.AddJoin(joinable.TableName, rhsAlias, lhsColumns, rhsColumns, joinType, condition);
outerjoin.AddJoins(joinable.FromJoinFragment(rhsAlias, false, true),
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/ANSIJoinFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/ANSIJoinFragment.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/ANSIJoinFragment.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -17,7 +17,7 @@
}
public override void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on)
+ SqlString on)
{
string joinString;
switch (joinType)
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/InformixJoinFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/InformixJoinFragment.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/InformixJoinFragment.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -40,7 +40,7 @@
}
public override void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on)
+ SqlString on)
{
//arbitrary on clause ignored!!
AddJoin(tableName, alias, fkColumns, pkColumns, joinType);
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/JoinFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/JoinFragment.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/JoinFragment.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -20,7 +20,7 @@
public abstract void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType);
public abstract void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on);
+ SqlString on);
public abstract void AddCrossJoin(string tableName, string alias);
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/OracleJoinFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/OracleJoinFragment.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/OracleJoinFragment.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -36,7 +36,7 @@
}
public override void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on)
+ SqlString on)
{
//arbitrary on clause ignored!!
AddJoin(tableName, alias, fkColumns, pkColumns, joinType);
@@ -62,9 +62,9 @@
/// was a normal join condition, but is natural
/// for a filter.
/// </summary>
- private void AddLeftOuterJoinCondition(string on)
+ private void AddLeftOuterJoinCondition(SqlString on)
{
- StringBuilder buf = new StringBuilder(on);
+ StringBuilder buf = new StringBuilder(on.ToString());
for (int i = 0; i < buf.Length; i++)
{
char character = buf[i];
@@ -76,7 +76,7 @@
i += 3;
}
}
- AddCondition(buf.ToString());
+ AddCondition(SqlString.Parse(buf.ToString()));
}
private static readonly ISet Operators = new HashedSet();
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/QueryJoinFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/QueryJoinFragment.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/QueryJoinFragment.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -25,7 +25,7 @@
}
private void AddJoin(string tableName, string alias, string concreteAlias, string[] fkColumns, string[] pkColumns,
- JoinType joinType, string on)
+ JoinType joinType, SqlString on)
{
if (!useThetaStyleInnerJoins || joinType != JoinType.InnerJoin)
{
@@ -42,7 +42,7 @@
}
public override void AddJoin(string tableName, string alias, string[] fkColumns, string[] pkColumns, JoinType joinType,
- string on)
+ SqlString on)
{
AddJoin(tableName, alias, alias, fkColumns, pkColumns, joinType, on);
}
Modified: trunk/nhibernate/src/NHibernate/Util/StringHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -496,9 +496,14 @@
public static bool IsNotEmpty(SqlString str)
{
- return str != null && str.Count > 0;
+ return !IsEmpty(str);
}
+ public static bool IsEmpty(SqlString str)
+ {
+ return str == null || str.Count == 0;
+ }
+
/// <summary>
///
/// </summary>
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-08-01 19:49:12 UTC (rev 5090)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-08-02 11:35:07 UTC (rev 5091)
@@ -1849,5 +1849,111 @@
criteria.List();
}
}
+
+
+ [Test]
+ public void AliasJoinCriterion()
+ {
+ using (ISession session = this.OpenSession())
+ {
+ using (ITransaction t = session.BeginTransaction())
+ {
+ Course courseA = new Course();
+ courseA.CourseCode = "HIB-A";
+ courseA.Description = "Hibernate Training A";
+ session.Persist(courseA);
+
+ Course courseB = new Course();
+ courseB.CourseCode = "HIB-B";
+ courseB.Description = "Hibernate Training B";
+ session.Persist(courseB);
+
+ Student gavin = new Student();
+ gavin.Name = "Gavin King";
+ gavin.StudentNumber = 232;
+ gavin.PreferredCourse = courseA;
+ session.Persist(gavin);
+
+ Student leonardo = new Student();
+ leonardo.Name = "Leonardo Quijano";
+ leonardo.StudentNumber = 233;
+ leonardo.PreferredCourse = courseB;
+ session.Persist(leonardo);
+
+ Student johnDoe = new Student();
+ johnDoe.Name = "John Doe";
+ johnDoe.StudentNumber = 235;
+ johnDoe.PreferredCourse = null;
+ session.Persist(johnDoe);
+
+ // test == on one value exists
+ IList<string> result = session.CreateCriteria<Student>()
+ .CreateAlias("PreferredCourse", "pc", JoinType.LeftOuterJoin,
+ Restrictions.Eq("pc.CourseCode", "HIB-A"))
+ .SetProjection(Property.ForName("pc.CourseCode"))
+ .AddOrder(Order.Asc("pc.CourseCode"))
+ .List<string>();
+
+ // can't be sure of NULL comparison ordering aside from they should
+ // either come first or last
+ if (result[0] == null)
+ {
+ Assert.IsNull(result[1]);
+ Assert.AreEqual("HIB-A", result[2]);
+ }
+ else
+ {
+ Assert.IsNull(result[2]);
+ Assert.IsNull(result[1]);
+ Assert.AreEqual("HIB-A", result[0]);
+ }
+
+ // test == on non existent value
+ result = session.CreateCriteria<Student>()
+ .CreateAlias("PreferredCourse", "pc", JoinType.LeftOuterJoin,
+ Restrictions.Eq("pc.CourseCode", "HIB-R"))
+ .SetProjection(Property.ForName("pc.CourseCode"))
+ .AddOrder(Order.Asc("pc.CourseCode"))
+ .List<string>();
+
+ Assert.AreEqual(3, result.Count);
+ Assert.IsNull(result[2]);
+ Assert.IsNull(result[1]);
+ Assert.IsNull(result[0]);
+
+ // test != on one existing value
+ result = session.CreateCriteria<Student>()
+ .CreateAlias("PreferredCourse", "pc", JoinType.LeftOuterJoin,
+ Restrictions.Not(Restrictions.Eq("pc.CourseCode", "HIB-A")))
+ .SetProjection(Property.ForName("pc.CourseCode"))
+ .AddOrder(Order.Asc("pc.CourseCode"))
+ .List<string>();
+
+ Assert.AreEqual(3, result.Count);
+
+ // can't be sure of NULL comparison ordering aside from they should
+ // either come first or last
+ if (result[0] == null)
+ {
+ Assert.IsNull(result[1]);
+ Assert.AreEqual("HIB-B", result[2]);
+ }
+ else
+ {
+ Assert.AreEqual("HIB-B", result[0]);
+ Assert.IsNull(result[1]);
+ Assert.IsNull(result[2]);
+ }
+
+ session.Delete(gavin);
+ session.Delete(leonardo);
+ session.Delete(johnDoe);
+ session.Delete(courseA);
+ session.Delete(courseB);
+
+ t.Commit();
+ }
+ }
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|