You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <fab...@us...> - 2009-11-28 12:32:17
|
Revision: 4864 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4864&view=rev Author: fabiomaulo Date: 2009-11-28 12:32:05 +0000 (Sat, 28 Nov 2009) Log Message: ----------- Minor (reformat) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:30:08 UTC (rev 4863) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:32:05 UTC (rev 4864) @@ -1,7 +1,5 @@ -using System; using System.Collections.Generic; using System.Xml; - using NHibernate.Cfg.MappingSchema; using NHibernate.Engine; using NHibernate.Mapping; @@ -11,11 +9,10 @@ { public class MappingRootBinder : Binder { + private readonly Dialect.Dialect dialect; private readonly XmlNamespaceManager namespaceManager; - private readonly Dialect.Dialect dialect; - public MappingRootBinder(Mappings mappings, XmlNamespaceManager namespaceManager, - Dialect.Dialect dialect) + public MappingRootBinder(Mappings mappings, XmlNamespaceManager namespaceManager, Dialect.Dialect dialect) : base(mappings) { this.namespaceManager = namespaceManager; @@ -43,19 +40,19 @@ private void AddEntitiesMappings(HbmMapping mappingSchema, IDictionary<string, MetaAttribute> inheritedMetas) { - foreach (var rootClass in mappingSchema.RootClasses) + foreach (HbmClass rootClass in mappingSchema.RootClasses) { AddRootClasses(Serialize(rootClass), rootClass, inheritedMetas); } - foreach (var subclass in mappingSchema.SubClasses) + foreach (HbmSubclass subclass in mappingSchema.SubClasses) { AddSubclasses(Serialize(subclass), subclass, inheritedMetas); } - foreach (var joinedSubclass in mappingSchema.JoinedSubclasses) + foreach (HbmJoinedSubclass joinedSubclass in mappingSchema.JoinedSubclasses) { AddJoinedSubclasses(Serialize(joinedSubclass), joinedSubclass, inheritedMetas); } - foreach (var unionSubclass in mappingSchema.UnionSubclasses) + foreach (HbmUnionSubclass unionSubclass in mappingSchema.UnionSubclasses) { AddUnionSubclasses(Serialize(unionSubclass), unionSubclass, inheritedMetas); } @@ -84,55 +81,61 @@ private void AddRootClasses(XmlNode parentNode, HbmClass rootClass, IDictionary<string, MetaAttribute> inheritedMetas) { - RootClassBinder binder = new RootClassBinder(this, namespaceManager, dialect); + var binder = new RootClassBinder(this, namespaceManager, dialect); binder.Bind(parentNode, rootClass, inheritedMetas); } - private void AddUnionSubclasses(XmlNode parentNode, HbmUnionSubclass unionSubclass, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddUnionSubclasses(XmlNode parentNode, HbmUnionSubclass unionSubclass, + IDictionary<string, MetaAttribute> inheritedMetas) { - UnionSubclassBinder binder = new UnionSubclassBinder(this, namespaceManager, dialect); + var binder = new UnionSubclassBinder(this, namespaceManager, dialect); binder.Bind(parentNode, inheritedMetas); } - private void AddJoinedSubclasses(XmlNode parentNode, HbmJoinedSubclass joinedSubclass, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddJoinedSubclasses(XmlNode parentNode, HbmJoinedSubclass joinedSubclass, + IDictionary<string, MetaAttribute> inheritedMetas) { - JoinedSubclassBinder binder = new JoinedSubclassBinder(this, namespaceManager, dialect); + var binder = new JoinedSubclassBinder(this, namespaceManager, dialect); binder.Bind(parentNode, inheritedMetas); } private void AddSubclasses(XmlNode parentNode, HbmSubclass subClass, IDictionary<string, MetaAttribute> inheritedMetas) { - SubclassBinder binder = new SubclassBinder(this, namespaceManager, dialect); + var binder = new SubclassBinder(this, namespaceManager, dialect); binder.Bind(parentNode, inheritedMetas); } private void AddQueries(HbmMapping mappingSchema) { - NamedQueryBinder binder = new NamedQueryBinder(this); + var binder = new NamedQueryBinder(this); foreach (object item in mappingSchema.Items1 ?? new object[0]) { - HbmQuery querySchema = item as HbmQuery; + var querySchema = item as HbmQuery; if (querySchema != null) + { binder.AddQuery(querySchema); + } } } private void AddSqlQueries(HbmMapping mappingSchema) { - NamedSQLQueryBinder binder = new NamedSQLQueryBinder(this); + var binder = new NamedSQLQueryBinder(this); foreach (object item in mappingSchema.Items1 ?? new object[0]) { - HbmSqlQuery sqlQuerySchema = item as HbmSqlQuery; + var sqlQuerySchema = item as HbmSqlQuery; if (sqlQuerySchema != null) + { binder.AddSqlQuery(sqlQuerySchema); + } } } @@ -155,7 +158,7 @@ string typeClass = FullQualifiedClassName(typedef.@class, mappings); string typeName = typedef.name; IEnumerable<HbmParam> paramIter = typedef.param ?? new HbmParam[0]; - Dictionary<string, string> parameters = new Dictionary<string, string>(5); + var parameters = new Dictionary<string, string>(5); foreach (HbmParam param in paramIter) { parameters.Add(param.name, param.GetText().Trim()); @@ -175,7 +178,7 @@ private void AddResultSetMappingDefinitions(HbmMapping mappingSchema) { - ResultSetMappingBinder binder = new ResultSetMappingBinder(this); + var binder = new ResultSetMappingBinder(this); foreach (HbmResultSet resultSetSchema in mappingSchema.resultset ?? new HbmResultSet[0]) { @@ -190,4 +193,4 @@ } } } -} +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-28 12:30:19
|
Revision: 4863 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4863&view=rev Author: fabiomaulo Date: 2009-11-28 12:30:08 +0000 (Sat, 28 Nov 2009) Log Message: ----------- Binders refactoring (the main binders working only with deserialized obj) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2009-11-28 12:00:44 UTC (rev 4862) +++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2009-11-28 12:30:08 UTC (rev 4863) @@ -8,11 +8,13 @@ using System.Text; using System.Xml; using System.Xml.Schema; +using System.Xml.Serialization; using Iesi.Collections; using Iesi.Collections.Generic; using log4net; using NHibernate.Bytecode; using NHibernate.Cfg.ConfigurationSchema; +using NHibernate.Cfg.MappingSchema; using NHibernate.Cfg.XmlHbmBinding; using NHibernate.Dialect; using NHibernate.Dialect.Function; @@ -507,7 +509,15 @@ Dialect.Dialect dialect = Dialect.Dialect.GetDialect(properties); Mappings mappings = CreateMappings(dialect); - new MappingRootBinder(mappings, namespaceManager, dialect).Bind(doc.Document.DocumentElement); + // TODO : The mappingMeta should be the property of NamedXmlDocument + // A validated document IS a deserialized doc and we don't need to deserialize it more than one time. + HbmMapping mappingMeta; + using (var reader = new StringReader(doc.Document.DocumentElement.OuterXml)) + { + mappingMeta= (HbmMapping) new XmlSerializer(typeof (HbmMapping)).Deserialize(reader); + } + + new MappingRootBinder(mappings, namespaceManager, dialect).Bind(mappingMeta); } catch (Exception e) { Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:00:44 UTC (rev 4862) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:30:08 UTC (rev 4863) @@ -22,10 +22,9 @@ this.dialect = dialect; } - public void Bind(XmlNode node) + public void Bind(HbmMapping mappingSchema) { IDictionary<string, MetaAttribute> inheritedMetas = EmptyMeta; - var mappingSchema = Deserialize<HbmMapping>(node); // get meta's from <hibernate-mapping> inheritedMetas = GetMetas(mappingSchema, inheritedMetas, true); @@ -33,7 +32,7 @@ AddFilterDefinitions(mappingSchema); AddTypeDefs(mappingSchema); - AddEntitiesMappings(node, mappingSchema, inheritedMetas); + AddEntitiesMappings(mappingSchema, inheritedMetas); AddQueries(mappingSchema); AddSqlQueries(mappingSchema); @@ -42,7 +41,7 @@ AddResultSetMappingDefinitions(mappingSchema); } - private void AddEntitiesMappings(XmlNode node, HbmMapping mappingSchema, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddEntitiesMappings(HbmMapping mappingSchema, IDictionary<string, MetaAttribute> inheritedMetas) { foreach (var rootClass in mappingSchema.RootClasses) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-28 12:00:53
|
Revision: 4862 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4862&view=rev Author: fabiomaulo Date: 2009-11-28 12:00:44 +0000 (Sat, 28 Nov 2009) Log Message: ----------- - Starting refactoring of binders - bug fixed for <meta> (the default inherit is true) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml Added Paths: ----------- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs 2009-11-28 12:00:44 UTC (rev 4862) @@ -1,3 +1,5 @@ +using System.Linq; + namespace NHibernate.Cfg.MappingSchema { partial class HbmMapping : AbstractDecoratable @@ -16,5 +18,25 @@ { return meta; } + + public HbmClass[] RootClasses + { + get { return Items != null ? Items.OfType<HbmClass>().ToArray():new HbmClass[0]; } + } + + public HbmSubclass[] SubClasses + { + get { return Items != null ? Items.OfType<HbmSubclass>().ToArray(): new HbmSubclass[0]; } + } + + public HbmJoinedSubclass[] JoinedSubclasses + { + get { return Items != null ? Items.OfType<HbmJoinedSubclass>().ToArray(): new HbmJoinedSubclass[0]; } + } + + public HbmUnionSubclass[] UnionSubclasses + { + get { return Items != null ? Items.OfType<HbmUnionSubclass>().ToArray(): new HbmUnionSubclass[0]; } + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs 2009-11-28 12:00:44 UTC (rev 4862) @@ -0,0 +1,7 @@ +namespace NHibernate.Cfg.MappingSchema +{ + public interface IEntityMetadata + { + + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs 2009-11-28 12:00:44 UTC (rev 4862) @@ -142,6 +142,24 @@ return (T) new XmlSerializer(typeof (T)).Deserialize(reader); } + protected static XmlNode Serialize<T>(T hbmElement) + { + // TODO : this method is only for TEMPORAL usage; should be removed after refactorize all binders + var serializer = new XmlSerializer(typeof (T)); + using (var memStream = new MemoryStream(2000)) + using (var xmlWriter = XmlWriter.Create(memStream)) + { + serializer.Serialize(xmlWriter, hbmElement); + memStream.Position = 0; + using (XmlReader reader = XmlReader.Create(memStream)) + { + var hbmDocument = new XmlDocument(); + hbmDocument.Load(reader); + return hbmDocument.DocumentElement; + } + } + } + protected static string GetXmlEnumAttribute(Enum cascadeStyle) { MemberInfo[] memberInfo = cascadeStyle.GetType().GetMember(cascadeStyle.ToString()); @@ -231,7 +249,7 @@ continue; } var inheritableValue = GetAttributeValue(metaNode, "inherit"); - bool inheritable = inheritableValue != null ? IsTrue(inheritableValue) : false; + bool inheritable = inheritableValue != null ? IsTrue(inheritableValue) : true; if (onlyInheritable & !inheritable) { continue; Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:00:44 UTC (rev 4862) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Xml; @@ -32,10 +33,7 @@ AddFilterDefinitions(mappingSchema); AddTypeDefs(mappingSchema); - AddRootClasses(node, inheritedMetas); - AddSubclasses(node, inheritedMetas); - AddJoinedSubclasses(node, inheritedMetas); - AddUnionSubclasses(node, inheritedMetas); + AddEntitiesMappings(node, mappingSchema, inheritedMetas); AddQueries(mappingSchema); AddSqlQueries(mappingSchema); @@ -44,6 +42,26 @@ AddResultSetMappingDefinitions(mappingSchema); } + private void AddEntitiesMappings(XmlNode node, HbmMapping mappingSchema, IDictionary<string, MetaAttribute> inheritedMetas) + { + foreach (var rootClass in mappingSchema.RootClasses) + { + AddRootClasses(Serialize(rootClass), rootClass, inheritedMetas); + } + foreach (var subclass in mappingSchema.SubClasses) + { + AddSubclasses(Serialize(subclass), subclass, inheritedMetas); + } + foreach (var joinedSubclass in mappingSchema.JoinedSubclasses) + { + AddJoinedSubclasses(Serialize(joinedSubclass), joinedSubclass, inheritedMetas); + } + foreach (var unionSubclass in mappingSchema.UnionSubclasses) + { + AddUnionSubclasses(Serialize(unionSubclass), unionSubclass, inheritedMetas); + } + } + private void SetMappingsProperties(HbmMapping mappingSchema) { mappings.SchemaName = mappingSchema.schema; @@ -65,36 +83,32 @@ } } - private void AddRootClasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddRootClasses(XmlNode parentNode, HbmClass rootClass, IDictionary<string, MetaAttribute> inheritedMetas) { RootClassBinder binder = new RootClassBinder(this, namespaceManager, dialect); - foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsClass, namespaceManager)) - binder.Bind(node, Deserialize<HbmClass>(node), inheritedMetas); + binder.Bind(parentNode, rootClass, inheritedMetas); } - private void AddUnionSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddUnionSubclasses(XmlNode parentNode, HbmUnionSubclass unionSubclass, IDictionary<string, MetaAttribute> inheritedMetas) { UnionSubclassBinder binder = new UnionSubclassBinder(this, namespaceManager, dialect); - foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsUnionSubclass, namespaceManager)) - binder.Bind(node, inheritedMetas); + binder.Bind(parentNode, inheritedMetas); } - private void AddJoinedSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddJoinedSubclasses(XmlNode parentNode, HbmJoinedSubclass joinedSubclass, IDictionary<string, MetaAttribute> inheritedMetas) { JoinedSubclassBinder binder = new JoinedSubclassBinder(this, namespaceManager, dialect); - foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsJoinedSubclass, namespaceManager)) - binder.Bind(node, inheritedMetas); + binder.Bind(parentNode, inheritedMetas); } - private void AddSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas) + private void AddSubclasses(XmlNode parentNode, HbmSubclass subClass, IDictionary<string, MetaAttribute> inheritedMetas) { SubclassBinder binder = new SubclassBinder(this, namespaceManager, dialect); - foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsSubclass, namespaceManager)) - binder.Bind(node, inheritedMetas); + binder.Bind(parentNode, inheritedMetas); } private void AddQueries(HbmMapping mappingSchema) Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-28 12:00:44 UTC (rev 4862) @@ -495,6 +495,7 @@ <Compile Include="Cfg\Loquacious\MappingsConfiguration.cs" /> <Compile Include="Cfg\Loquacious\ProxyConfiguration.cs" /> <Compile Include="Cfg\MappingSchema\HbmDefinition.cs" /> + <Compile Include="Cfg\MappingSchema\IEntityMetadata.cs" /> <Compile Include="Cfg\SchemaAutoAction.cs" /> <Compile Include="Cfg\SessionFactoryConfigurationBase.cs" /> <Compile Include="Cfg\ISessionFactoryConfiguration.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs 2009-11-28 12:00:44 UTC (rev 4862) @@ -157,7 +157,7 @@ Assert.That(propertyAttribute.Value, Is.EqualTo("monetaryamount anotherSet composite property empinone level")); } - [Test] + [Test, Ignore("Not fixed, see the TODO of this test.")] public void Comparator() { PersistentClass cm = cfg.GetClassMapping("NHibernate.Test.MappingTest.Wicked"); Modified: trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml 2009-11-27 20:10:47 UTC (rev 4861) +++ trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml 2009-11-28 12:00:44 UTC (rev 4862) @@ -30,7 +30,8 @@ </property> </component> - <set name="SortedEmployee" sort="NonExistingComparator"> + <!--<set name="SortedEmployee" sort="NonExistingComparator">--> + <set name="SortedEmployee"> <meta attribute="globalmutated">sortedemployee level</meta> <key column="attrb_id"/> <many-to-many class="Employee" column="id"/> @@ -71,7 +72,7 @@ <property name="Pregnant"/> <property name="Birthdate" type="Date"/> <subclass name="DomesticAnimal"> - <meta attribute="Auditable"/> + <meta attribute="Auditable" inherit="true"/> <property name="Name"/> <many-to-one name="Owner"/> <subclass name="Cat"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2009-11-27 20:10:59
|
Revision: 4861 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4861&view=rev Author: steverstrong Date: 2009-11-27 20:10:47 +0000 (Fri, 27 Nov 2009) Log Message: ----------- Further Linq test cases added, and various related bugs fixed Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs trunk/nhibernate/src/NHibernate.Test/Linq/PropertyMethodMappingTests.cs trunk/nhibernate/src/NHibernate.Test/Linq/QueryReuseTests.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -261,9 +261,9 @@ return new HqlBitwiseNot(_factory); } - public HqlNot Not(HqlBooleanExpression operand) + public HqlBooleanNot Not(HqlBooleanExpression operand) { - return new HqlNot(_factory, operand); + return new HqlBooleanNot(_factory, operand); } public HqlAverage Average(HqlExpression expression) @@ -360,5 +360,16 @@ { return new HqlDistinctHolder(_factory, children); } + + public HqlIsNull IsNull(HqlExpression lhs) + { + return new HqlIsNull(_factory, lhs); + } + + public HqlIsNotNull IsNotNull(HqlExpression lhs) + { + return new HqlIsNotNull(_factory, lhs); + } } + } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -192,6 +192,9 @@ case TypeCode.Int32: SetText("integer"); break; + case TypeCode.Int64: + SetText("long"); + break; case TypeCode.Decimal: SetText("decimal"); break; @@ -201,6 +204,9 @@ case TypeCode.String: SetText("string"); break; + case TypeCode.Double: + SetText("double"); + break; default: if (type == typeof(Guid)) { @@ -299,7 +305,7 @@ public class HqlBooleanAnd : HqlBooleanExpression { public HqlBooleanAnd(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs) - : base(HqlSqlWalker.AND, "/", factory, lhs, rhs) + : base(HqlSqlWalker.AND, "and", factory, lhs, rhs) { } } @@ -576,9 +582,9 @@ } } - public class HqlNot : HqlBooleanExpression + public class HqlBooleanNot : HqlBooleanExpression { - public HqlNot(IASTFactory factory, HqlBooleanExpression operand) + public HqlBooleanNot(IASTFactory factory, HqlBooleanExpression operand) : base(HqlSqlWalker.NOT, "not", factory, operand) { } @@ -712,4 +718,19 @@ { } } + + public class HqlIsNull : HqlBooleanExpression + { + public HqlIsNull(IASTFactory factory, HqlExpression lhs) + : base(HqlSqlWalker.IS_NULL, "is null", factory, lhs) + { + } + } + + public class HqlIsNotNull : HqlBooleanExpression + { + public HqlIsNotNull(IASTFactory factory, HqlExpression lhs) : base(HqlSqlWalker.IS_NOT_NULL, "is not null", factory, lhs) + { + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -336,11 +336,14 @@ throw new ArgumentNullException("val", "A type specific Set(name, val) should be called because the Type can not be guessed from a null value."); } - } + + SetParameter(name, val, type); + } else { SetParameter(name, val, DetermineType(name, val)); } + return this; } Modified: trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -3,6 +3,7 @@ using System.Linq; using System.Linq.Expressions; using NHibernate.Hql.Ast; +using NHibernate.Type; namespace NHibernate.Linq { @@ -10,9 +11,9 @@ { public HqlQuery Statement { get; private set; } public ResultTransformer ResultTransformer { get; private set; } - public List<Action<IQuery, IDictionary<string, object>>> AdditionalCriteria { get; private set; } + public List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> AdditionalCriteria { get; private set; } - public ExpressionToHqlTranslationResults(HqlQuery statement, IList<LambdaExpression> itemTransformers, IList<LambdaExpression> listTransformers, List<Action<IQuery, IDictionary<string, object>>> additionalCriteria) + public ExpressionToHqlTranslationResults(HqlQuery statement, IList<LambdaExpression> itemTransformers, IList<LambdaExpression> listTransformers, List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> additionalCriteria) { Statement = statement; Modified: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -1,11 +1,37 @@ -using System.Linq.Expressions; +using System; +using System.Linq.Expressions; namespace NHibernate.Linq.Expressions { public class NhAverageExpression : NhAggregatedExpression { - public NhAverageExpression(Expression expression) : base(expression, NhExpressionType.Average) + public NhAverageExpression(Expression expression) : base(expression, CalculateAverageType(expression.Type), NhExpressionType.Average) { } + + private static System.Type CalculateAverageType(System.Type inputType) + { + bool isNullable = false; + + if (inputType.IsNullable()) + { + isNullable = true; + inputType = inputType.NullableOf(); + } + + switch (System.Type.GetTypeCode(inputType)) + { + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Single: + case TypeCode.Double: + return isNullable ? typeof(double?) : typeof (double); + case TypeCode.Decimal: + return isNullable ? typeof(decimal?) : typeof(decimal); + } + + throw new NotSupportedException(inputType.FullName); + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -4,9 +4,25 @@ { public class NhCountExpression : NhAggregatedExpression { - public NhCountExpression(Expression expression) - : base(expression, typeof(int), NhExpressionType.Count) + public NhCountExpression(Expression expression, System.Type type) + : base(expression, type, NhExpressionType.Count) { } } -} \ No newline at end of file + + public class NhShortCountExpression : NhCountExpression + { + public NhShortCountExpression(Expression expression) + : base(expression, typeof(int)) + { + } + } + + public class NhLongCountExpression : NhCountExpression + { + public NhLongCountExpression(Expression expression) + : base(expression, typeof(long)) + { + } + } +} Modified: trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -24,5 +24,10 @@ return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)); } + public static System.Type NullableOf(this System.Type type) + { + return type.GetGenericArguments()[0]; + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -1,3 +1,6 @@ +using System; +using NHibernate.Type; + namespace NHibernate.Linq { public class NamedParameter @@ -2,10 +5,12 @@ { - public NamedParameter(string name, object value) + public NamedParameter(string name, object value, IType type) { Name = name; Value = value; + Type = type; } - public string Name { get; set; } - public object Value { get; set; } + public string Name { get; private set; } + public object Value { get; internal set; } + public IType Type { get; internal set; } } Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -6,6 +6,7 @@ using NHibernate.Hql.Ast.ANTLR.Tree; using NHibernate.Linq.ResultOperators; using NHibernate.Linq.Visitors; +using NHibernate.Type; using Remotion.Data.Linq; using Remotion.Data.Linq.Clauses; using Remotion.Data.Linq.Clauses.StreamedData; @@ -25,7 +26,7 @@ public NhLinqExpressionReturnType ReturnType { get; private set; } - public IDictionary<string, object> ParameterValuesByName { get; private set; } + public IDictionary<string, Pair<object, IType>> ParameterValuesByName { get; private set; } public ExpressionToHqlTranslationResults ExpressionToHqlTranslationResults { get; private set; } @@ -40,7 +41,10 @@ _constantToParameterMap = ExpressionParameterVisitor.Visit(_expression); - ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name, p => p.Value); + ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name, + p => + new Pair<object, IType> + {Left = p.Value, Right = p.Type}); Key = ExpressionKeyVisitor.Visit(_expression, _constantToParameterMap); Modified: trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -3,6 +3,7 @@ using System.Linq; using System.Linq.Expressions; using NHibernate.Impl; +using NHibernate.Type; namespace NHibernate.Linq { @@ -51,15 +52,23 @@ return new NhQueryable<T>(this, expression); } - static void SetParameters(IQuery query, IDictionary<string, object> parameters) + static void SetParameters(IQuery query, IDictionary<string, Pair<object, IType>> parameters) { foreach (var parameterName in query.NamedParameters) { - query.SetParameter(parameterName, parameters[parameterName]); + var param = parameters[parameterName]; + if (param.Left == null) + { + query.SetParameter(parameterName, param.Left, param.Right); + } + else + { + query.SetParameter(parameterName, param.Left); + } } } - public void SetResultTransformerAndAdditionalCriteria(IQuery query, IDictionary<string, object> parameters) + public void SetResultTransformerAndAdditionalCriteria(IQuery query, IDictionary<string, Pair<object, IType>> parameters) { var queryImpl = (ExpressionQueryImpl) query; @@ -73,4 +82,10 @@ } } } + + public class Pair<TLeft, TRight> + { + public TLeft Left { get; set; } + public TRight Right { get; set; } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NHibernate.Type; namespace NHibernate.Linq { @@ -6,9 +7,9 @@ { private readonly List<NamedParameter> _parameters = new List<NamedParameter>(); - public NamedParameter AddParameter(object value) + public NamedParameter AddParameter(object value, IType type) { - var parameter = new NamedParameter("p" + (_parameters.Count + 1), value); + var parameter = new NamedParameter("p" + (_parameters.Count + 1), value, type); _parameters.Add(parameter); return parameter; } Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -53,9 +53,14 @@ } else if (resultOperator is CountResultOperator) { - queryModel.SelectClause.Selector = new NhCountExpression(queryModel.SelectClause.Selector); + queryModel.SelectClause.Selector = new NhShortCountExpression(queryModel.SelectClause.Selector); queryModel.ResultOperators.Remove(resultOperator); } + else if (resultOperator is LongCountResultOperator) + { + queryModel.SelectClause.Selector = new NhLongCountExpression(queryModel.SelectClause.Selector); + queryModel.ResultOperators.Remove(resultOperator); + } base.VisitResultOperator(resultOperator, queryModel, index); } @@ -89,7 +94,7 @@ { case "Count": return CreateAggregate(m.Arguments[0], (LambdaExpression)m.Arguments[1], - e => new NhCountExpression(e)); + e => new NhShortCountExpression(e)); case "Min": return CreateAggregate(m.Arguments[0], (LambdaExpression) m.Arguments[1], e => new NhMinExpression(e)); Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -25,7 +25,7 @@ { if (!typeof(IQueryable).IsAssignableFrom(expression.Type)) { - _parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value)); + _parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value, NHibernateUtil.GuessType(expression.Type))); } return base.VisitConstantExpression(expression); Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -201,8 +201,31 @@ _hqlTreeBuilder.Case( new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) }, _hqlTreeBuilder.Constant(0)); + + return _hqlTreeBuilder.Equality(lhs, rhs); } + // Also check for nullability + if (expression.Left.Type.IsNullable() || expression.Right.Type.IsNullable()) + { + // TODO - yuck. This clone is needed because the AST tree nodes are not immutable, + // and sharing nodes between multiple branches will cause issues in the hqlSqlWalker phase - + // a node, x, gets visited during the walk and updated to refer to a real property. Later in + // the walk, x get revisited (since we copied it here), but now the type doesn't match what + // the parser expects. So we can't share. Implementing Clone() on HqlTreeNode would be better + // that doing a full visit of the Expression tree. Allowing shared nodes in the AST would be better + // still, but might be more work + var lhs2 = VisitExpression(expression.Left).AsExpression(); + var rhs2 = VisitExpression(expression.Right).AsExpression(); + + return _hqlTreeBuilder.BooleanOr( + _hqlTreeBuilder.BooleanAnd( + _hqlTreeBuilder.IsNull(lhs), + _hqlTreeBuilder.IsNull(rhs)), + _hqlTreeBuilder.Equality(lhs2, rhs2) + ); + } + return _hqlTreeBuilder.Equality(lhs, rhs); case ExpressionType.NotEqual: @@ -218,8 +241,32 @@ _hqlTreeBuilder.Case( new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) }, _hqlTreeBuilder.Constant(0)); + + return _hqlTreeBuilder.Inequality(lhs, rhs); + } + // Also check for nullability + if (expression.Left.Type.IsNullable() || expression.Right.Type.IsNullable()) + { + var lhs2 = VisitExpression(expression.Left).AsExpression(); + var rhs2 = VisitExpression(expression.Right).AsExpression(); + var lhs3 = VisitExpression(expression.Left).AsExpression(); + var rhs3 = VisitExpression(expression.Right).AsExpression(); + + return + _hqlTreeBuilder.BooleanOr( + _hqlTreeBuilder.BooleanOr( + _hqlTreeBuilder.BooleanAnd( + _hqlTreeBuilder.IsNull(lhs), + _hqlTreeBuilder.IsNotNull(rhs)), + _hqlTreeBuilder.BooleanAnd( + _hqlTreeBuilder.IsNotNull(lhs2), + _hqlTreeBuilder.IsNull(rhs2)) + ), + _hqlTreeBuilder.Inequality(lhs3, rhs3)); + } + return _hqlTreeBuilder.Inequality(lhs, rhs); case ExpressionType.And: Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -69,7 +69,7 @@ { Expression nx = base.VisitExpression(expression.Expression); - return nx != expression.Expression ? new NhCountExpression(nx) : expression; + return nx != expression.Expression ? new NhShortCountExpression(nx) : expression; } protected virtual Expression VisitNhSum(NhSumExpression expression) Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -85,7 +85,7 @@ { Expression nx = base.VisitExpression(expression.Expression); - return nx != expression.Expression ? new NhCountExpression(nx) : expression; + return nx != expression.Expression ? new NhCountExpression(nx, expression.Type) : expression; } protected virtual Expression BaseVisitNhSum(NhSumExpression expression) Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -9,6 +9,7 @@ using NHibernate.Linq.GroupJoin; using NHibernate.Linq.ResultOperators; using NHibernate.Linq.ReWriters; +using NHibernate.Type; using Remotion.Data.Linq; using Remotion.Data.Linq.Clauses; using Remotion.Data.Linq.Clauses.Expressions; @@ -49,7 +50,7 @@ private readonly HqlTreeBuilder _hqlTreeBuilder; - private readonly List<Action<IQuery, IDictionary<string, object>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, object>>>(); + private readonly List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, Pair<object, IType>>>>(); private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>(); private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>(); @@ -200,6 +201,10 @@ { ProcessGroupByOperator((GroupResultOperator)resultOperator); } + else if (resultOperator is SingleResultOperator) + { + ProcessSingleOperator((SingleResultOperator) resultOperator); + } else { throw new NotSupportedException(string.Format("The {0} result operator is not current supported", @@ -207,6 +212,23 @@ } } + private void ProcessSingleOperator(SingleResultOperator resultOperator) + { + Expression<Func<IEnumerable<object>, object>> lambda; + + if (resultOperator.ReturnDefaultWhenEmpty) + { + lambda = (IEnumerable<object> list) => list.SingleOrDefault(); + } + else + { + lambda = (IEnumerable<object> list) => list.Single(); + } + + _additionalCriteria.Add((q, p) => q.SetMaxResults(1)); + _listTransformers.Add(lambda); + } + private void ProcessClientSideResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel) { if (resultOperator is NonAggregatingGroupBy) @@ -307,7 +329,7 @@ // clause to see if it is valid if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) { - _additionalCriteria.Add((q, p) => q.SetMaxResults((int) p[parameterName.Name])); + _additionalCriteria.Add((q, p) => q.SetMaxResults((int) p[parameterName.Name].Left)); } else { @@ -321,7 +343,7 @@ if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) { - _additionalCriteria.Add((q, p) => q.SetFirstResult((int)p[parameterName.Name])); + _additionalCriteria.Add((q, p) => q.SetFirstResult((int)p[parameterName.Name].Left)); } else { @@ -389,19 +411,6 @@ _listTransformers.Add(lambdaExpr); return; - /* - _listTransformers.Add(Expression.Lambda( - Expression.Call(toList, - Expression.Call(groupByMethod, - Expression.Call(castToItem, - Expression.Call(selectObject, - Expression.Call( - castToObjectArray, - listParameter), - index)), - keySelectorExpr) - ), - listParameter));*/ } private static System.Type SourceOf(Expression keySelector) Modified: trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -3538,7 +3538,7 @@ orderLine = new OrderLine { Order = orders.Where(o => o.OrderId == 11077 ).First(), Product = products.Where(p => p.Name == "Original Frankfurter grüne Soße").First(), UnitPrice = 13.00M, Quantity = 2, Discount = 0M }; session.Insert(orderLine); } - protected override void OnFixtureSetup() + protected override void OnFixtureSetup() { CreateTestData(); } Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -50,8 +50,8 @@ Assert.AreEqual(nhLondon.Key, nhNewYork.Key); Assert.AreEqual(1, nhLondon.ParameterValuesByName.Count); Assert.AreEqual(1, nhNewYork.ParameterValuesByName.Count); - Assert.AreEqual("London", nhLondon.ParameterValuesByName.First().Value); - Assert.AreEqual("New York", nhNewYork.ParameterValuesByName.First().Value); + Assert.AreEqual("London", nhLondon.ParameterValuesByName.First().Value.Left); + Assert.AreEqual("New York", nhNewYork.ParameterValuesByName.First().Value.Left); } } Added: trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class ProjectionsTests : LinqTestCase + { + [Test] + public void ProjectAnonymousTypeWithWhere() + { + var query = (from user in db.Users + where user.Name == "ayende" + select user.Name) + .First(); + Assert.AreEqual("ayende", query); + } + + + [Test] + public void ProjectConditionals() + { + var query = (from user in db.Users + orderby user.Id + select new { user.Id, GreaterThan2 = user.Id > 2 ? "Yes" : "No" }) + .ToList(); + Assert.AreEqual("No", query[0].GreaterThan2); + Assert.AreEqual("No", query[1].GreaterThan2); + Assert.AreEqual("Yes", query[2].GreaterThan2); + } + + [Test] + public void ProjectAnonymousTypeWithMultiply() + { + var query = (from user in db.Users + select new { user.Name, user.Id, Id2 = user.Id * 2 }) + .ToList(); + Assert.AreEqual(3, query.Count); + foreach (var user in query) + { + Assert.AreEqual(user.Id * 2, user.Id2); + } + } + + [Test] + public void ProjectAnonymousTypeWithSubstraction() + { + var query = (from user in db.Users + select new { user.Name, user.Id, Id2 = user.Id - 2 }) + .ToList(); + Assert.AreEqual(3, query.Count); + foreach (var user in query) + { + Assert.AreEqual(user.Id - 2, user.Id2); + } + } + + [Test] + public void ProjectAnonymousTypeWithDivision() + { + var query = (from user in db.Users + select new { user.Name, user.Id, Id2 = (user.Id * 10) / 2 }) + .ToList(); + Assert.AreEqual(3, query.Count); + foreach (var user in query) + { + Assert.AreEqual((user.Id * 10) / 2, user.Id2); + } + } + + [Test] + public void ProjectAnonymousTypeWithAddition() + { + var query = (from user in db.Users + select new { user.Name, user.Id, Id2 = (user.Id + 101) }) + .ToList(); + Assert.AreEqual(3, query.Count); + foreach (var user in query) + { + Assert.AreEqual((user.Id + 101), user.Id2); + } + } + + [Test] + public void ProjectAnonymousTypeAndConcatenateFields() + { + var query = (from user in db.Users + orderby user.Name + select new { DoubleName = user.Name + " " + user.Name, user.RegisteredAt } + + ) + .ToList(); + + Assert.AreEqual("ayende ayende", query[0].DoubleName); + Assert.AreEqual("nhibernate nhibernate", query[1].DoubleName); + Assert.AreEqual("rahien rahien", query[2].DoubleName); + + + Assert.AreEqual(DateTime.Today, query[0].RegisteredAt); + Assert.AreEqual(new DateTime(2000, 1, 1), query[1].RegisteredAt); + Assert.AreEqual(new DateTime(1998, 12, 31), query[2].RegisteredAt); + } + + [Test] + public void ProjectKnownType() + { + var query = (from user in db.Users + orderby user.Id + select new KeyValuePair<string, DateTime>(user.Name, user.RegisteredAt)) + .ToList(); + + Assert.AreEqual("ayende", query[0].Key); + Assert.AreEqual("rahien", query[1].Key); + Assert.AreEqual("nhibernate", query[2].Key); + + + Assert.AreEqual(DateTime.Today, query[0].Value); + Assert.AreEqual(new DateTime(1998, 12, 31), query[1].Value); + Assert.AreEqual(new DateTime(2000, 1, 1), query[2].Value); + } + + [Test] + public void ProjectAnonymousType() + { + var query = (from user in db.Users + orderby user.Id + select new { user.Name, user.RegisteredAt }) + .ToList(); + Assert.AreEqual("ayende", query[0].Name); + Assert.AreEqual("rahien", query[1].Name); + Assert.AreEqual("nhibernate", query[2].Name); + + + Assert.AreEqual(DateTime.Today, query[0].RegisteredAt); + Assert.AreEqual(new DateTime(1998, 12, 31), query[1].RegisteredAt); + Assert.AreEqual(new DateTime(2000, 1, 1), query[2].RegisteredAt); + } + + [Test] + public void ProjectUserNames() + { + var query = (from user in db.Users + select user.Name).ToList(); + Assert.AreEqual(3, query.Count); + Assert.AreEqual(3, query.Intersect(new[] { "ayende", "rahien", "nhibernate" }) + .ToList().Count); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/PropertyMethodMappingTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/PropertyMethodMappingTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/PropertyMethodMappingTests.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -0,0 +1,30 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class PropertyMethodMappingTests : LinqTestCase + { + [Test] + public void CanExecuteCountInSelectClause() + { + var results = db.Timesheets + .Select(t => t.Entries.Count).ToList(); + + Assert.AreEqual(3, results.Count); + Assert.AreEqual(0, results[0]); + Assert.AreEqual(2, results[1]); + Assert.AreEqual(4, results[2]); + } + + [Test] + public void CanExecuteCountInWhereClause() + { + var results = db.Timesheets + .Where(t => t.Entries.Count >= 2).ToList(); + + Assert.AreEqual(2, results.Count); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/QueryReuseTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/QueryReuseTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/QueryReuseTests.cs 2009-11-27 20:10:47 UTC (rev 4861) @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.Test.Linq.Entities; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class QueryReuseTests : LinqTestCase + { + private IQueryable<User> _query; + + protected override void OnSetUp() + { + base.OnSetUp(); + + _query = db.Users; + } + + private void AssertQueryReuseable(IQueryable<User> query) + { + IList<User> users = _query.ToList(); + Assert.AreEqual(3, users.Count); + } + + [Test] + public void CanReuseAfterFirst() + { + User user = _query.First(u => u.Name == "rahien"); + + Assert.IsNotNull(user); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterFirstOrDefault() + { + User user = _query.FirstOrDefault(u => u.Name == "rahien"); + + Assert.IsNotNull(user); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterSingle() + { + User user = _query.Single(u => u.Name == "rahien"); + + Assert.IsNotNull(user); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterSingleOrDefault() + { + User user = _query.SingleOrDefault(u => u.Name == "rahien"); + + Assert.IsNotNull(user); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterAggregate() + { + User user = _query.Aggregate((u1, u2) => u1); + + Assert.IsNotNull(user); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterAverage() + { + double average = _query.Average(u => u.InvalidLoginAttempts); + + Assert.AreEqual(5.0, average); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterCount() + { + int totalCount = _query.Count(); + + Assert.AreEqual(3, totalCount); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterCountWithPredicate() + { + int count = _query.Count(u => u.LastLoginDate != null); + + Assert.AreEqual(1, count); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterLongCount() + { + long totalCount = _query.LongCount(); + + Assert.AreEqual(3, totalCount); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterLongCountWithPredicate() + { + long totalCount = _query.LongCount(u => u.LastLoginDate != null); + + Assert.AreEqual(1, totalCount); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterMax() + { + int max = _query.Max(u => u.InvalidLoginAttempts); + + Assert.AreEqual(6, max); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterMin() + { + int min = _query.Min(u => u.InvalidLoginAttempts); + + Assert.AreEqual(4, min); + AssertQueryReuseable(_query); + } + + [Test] + public void CanReuseAfterSum() + { + int sum = _query.Sum(u => u.InvalidLoginAttempts); + + Assert.AreEqual(4 + 5 + 6, sum); + AssertQueryReuseable(_query); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-27 18:12:00 UTC (rev 4860) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-27 20:10:47 UTC (rev 4861) @@ -417,6 +417,9 @@ <Compile Include="Linq\PagingTests.cs" /> <Compile Include="Linq\ParameterisedQueries.cs" /> <Compile Include="Linq\PatientTests.cs" /> + <Compile Include="Linq\ProjectionsTests.cs" /> + <Compile Include="Linq\PropertyMethodMappingTests.cs" /> + <Compile Include="Linq\QueryReuseTests.cs" /> <Compile Include="Linq\ReadonlyTestCase.cs" /> <Compile Include="MappingTest\NonReflectiveBinderFixture.cs" /> <Compile Include="MappingTest\Wicked.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-27 18:12:08
|
Revision: 4860 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4860&view=rev Author: fabiomaulo Date: 2009-11-27 18:12:00 +0000 (Fri, 27 Nov 2009) Log Message: ----------- Refactoring (improvement of performance parsing mappings) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs 2009-11-25 21:46:06 UTC (rev 4859) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs 2009-11-27 18:12:00 UTC (rev 4860) @@ -10,36 +10,39 @@ private const string CfgSchemaResource = "NHibernate.nhibernate-configuration.xsd"; private const string MappingSchemaResource = "NHibernate.nhibernate-mapping.xsd"; - private readonly XmlSchema config = ReadXmlSchemaFromEmbeddedResource(CfgSchemaResource); - private readonly XmlSchema mapping = ReadXmlSchemaFromEmbeddedResource(MappingSchemaResource); + private static readonly XmlSchemaSet ConfigSchemaSet = ReadXmlSchemaFromEmbeddedResource(CfgSchemaResource); + private static readonly XmlSchemaSet MappingSchemaSet = ReadXmlSchemaFromEmbeddedResource(MappingSchemaResource); public XmlReaderSettings CreateConfigReaderSettings() { - XmlReaderSettings result = CreateXmlReaderSettings(config); - result.ValidationEventHandler += new ValidationEventHandler(ConfigSettingsValidationEventHandler); + XmlReaderSettings result = CreateXmlReaderSettings(ConfigSchemaSet); + result.ValidationEventHandler += ConfigSettingsValidationEventHandler; result.IgnoreComments = true; return result; } public XmlReaderSettings CreateMappingReaderSettings() { - return CreateXmlReaderSettings(mapping); + return CreateXmlReaderSettings(MappingSchemaSet); } - private static XmlSchema ReadXmlSchemaFromEmbeddedResource(string resourceName) + private static XmlSchemaSet ReadXmlSchemaFromEmbeddedResource(string resourceName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using (Stream resourceStream = executingAssembly.GetManifestResourceStream(resourceName)) - return XmlSchema.Read(resourceStream, null); + { + var xmlSchema = XmlSchema.Read(resourceStream, null); + var xmlSchemaSet = new XmlSchemaSet(); + xmlSchemaSet.Add(xmlSchema); + xmlSchemaSet.Compile(); + return xmlSchemaSet; + } } - private static XmlReaderSettings CreateXmlReaderSettings(XmlSchema xmlSchema) + private static XmlReaderSettings CreateXmlReaderSettings(XmlSchemaSet xmlSchemaSet) { - XmlReaderSettings settings = new XmlReaderSettings(); - settings.ValidationType = ValidationType.Schema; - settings.Schemas.Add(xmlSchema); - return settings; + return new XmlReaderSettings {ValidationType = ValidationType.Schema, Schemas = xmlSchemaSet}; } private static void ConfigSettingsValidationEventHandler(object sender, ValidationEventArgs e) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2009-11-25 21:46:15
|
Revision: 4859 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4859&view=rev Author: steverstrong Date: 2009-11-25 21:46:06 +0000 (Wed, 25 Nov 2009) Log Message: ----------- More Linq test cases added Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Patient.cs trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Patient.hbm.xml trunk/nhibernate/src/NHibernate.Test/Linq/OrderByTests.cs trunk/nhibernate/src/NHibernate.Test/Linq/PagingTests.cs trunk/nhibernate/src/NHibernate.Test/Linq/PatientTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs 2009-11-25 20:16:50 UTC (rev 4858) +++ trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -1,4 +1,6 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.Linq; using NHibernate.Linq; namespace NHibernate.Test.Linq.Entities @@ -61,5 +63,25 @@ { get { return _session.Query<User>(); } } + + public IQueryable<PatientRecord> PatientRecords + { + get { return _session.Query<PatientRecord>(); } + } + + public IQueryable<State> States + { + get { return _session.Query<State>(); } + } + + public IQueryable<Patient> Patients + { + get { return _session.Query<Patient>(); } + } + + public IQueryable<Physician> Physicians + { + get { return _session.Query<Physician>(); } + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Patient.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Patient.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Patient.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.Linq.Entities +{ + public class Patient + { + private IList<PatientRecord> patientRecords; + private bool active; + private Physician physician; + + protected Patient() { } + public Patient(IEnumerable<PatientRecord> patientRecords, bool active, Physician physician) + { + this.active = active; + this.physician = physician; + this.patientRecords = new List<PatientRecord>(patientRecords); + foreach (var record in this.patientRecords) + { + record.Patient = this; + } + } + + public virtual long Id { get; set; } + + public virtual bool Active + { + get { return active; } + set { active = value; } + } + + public virtual IList<PatientRecord> PatientRecords + { + get { return patientRecords; } + set { patientRecords = value; } + } + + public virtual Physician Physician + { + get { return physician; } + set { physician = value; } + } + } + + public class Physician + { + public virtual long Id { get; set; } + public virtual string Name { get; set; } + } + + public class PatientRecord + { + public virtual long Id { get; set; } + public virtual PatientName Name { get; set; } + public virtual DateTime BirthDate { get; set; } + public virtual Gender Gender { get; set; } + public virtual PatientAddress Address { get; set; } + public virtual Patient Patient { get; set; } + } + + public enum Gender + { + Unknown, + Male, + Female + } + + public class PatientName + { + public virtual string FirstName { get; set; } + public virtual string LastName { get; set; } + } + + public class PatientAddress + { + public virtual string AddressLine1 { get; set; } + public virtual string AddressLine2 { get; set; } + public virtual string City { get; set; } + public virtual State State { get; set; } + public virtual string ZipCode { get; set; } + } + public class State + { + public virtual long Id { get; set; } + public virtual string Abbreviation { get; set; } + public virtual string FullName { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-25 20:16:50 UTC (rev 4858) +++ trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -49,7 +49,8 @@ "Linq.Mappings.Role.hbm.xml", "Linq.Mappings.User.hbm.xml", "Linq.Mappings.TimeSheet.hbm.xml", - "Linq.Mappings.Animal.hbm.xml" + "Linq.Mappings.Animal.hbm.xml", + "Linq.Mappings.Patient.hbm.xml" }; } @@ -69,7 +70,7 @@ using (ITransaction tx = session.BeginTransaction()) { CreateMiscTestData(session); - + CreatePatientData(session); tx.Commit(); } } @@ -220,6 +221,93 @@ session.Save(animal); } + private void CreatePatientData(ISession session) + { + State newYork = new State + { + Abbreviation = "NY", + FullName = "New York" + }; + State florida = new State + { + Abbreviation = "FL", + FullName = "Florida" + }; + + Physician drDobbs = new Physician + { + Name = "Dr Dobbs" + }; + Physician drWatson = new Physician + { + Name = "Dr Watson" + }; + + PatientRecord bobBarkerRecord = new PatientRecord + { + Name = new PatientName + { + FirstName = "Bob", + LastName = "Barker" + }, + Address = new PatientAddress + { + AddressLine1 = "123 Main St", + City = "New York", + State = newYork, + ZipCode = "10001" + }, + BirthDate = new DateTime(1930, 1, 1), + Gender = Gender.Male + }; + + PatientRecord johnDoeRecord1 = new PatientRecord + { + Name = new PatientName + { + FirstName = "John", + LastName = "Doe" + }, + Address = new PatientAddress + { + AddressLine1 = "123 Main St", + City = "Tampa", + State = florida, + ZipCode = "33602" + }, + BirthDate = new DateTime(1969, 1, 1), + Gender = Gender.Male + }; + + PatientRecord johnDoeRecord2 = new PatientRecord + { + Name = new PatientName + { + FirstName = "John", + LastName = "Doe" + }, + Address = new PatientAddress + { + AddressLine1 = "123 Main St", + AddressLine2 = "Apt 2", + City = "Tampa", + State = florida, + ZipCode = "33602" + }, + BirthDate = new DateTime(1969, 1, 1) + }; + + Patient bobBarker = new Patient(new[] { bobBarkerRecord }, false, drDobbs); + Patient johnDoe = new Patient(new[] { johnDoeRecord1, johnDoeRecord2 }, true, drWatson); + + session.Save(newYork); + session.Save(florida); + session.Save(drDobbs); + session.Save(drWatson); + session.Save(bobBarker); + session.Save(johnDoe); + } + private void CreateNorthwindData(IStatelessSession session) { var shippers = new List<Shipper>(); Added: trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Patient.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Patient.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Patient.hbm.xml 2009-11-25 21:46:06 UTC (rev 4859) @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.Test.Linq.Entities" assembly="NHibernate.Test"> + <class name="Patient" table="Patients"> + <id name="Id" column="PatientId" type="Int64"> + <generator class="native" /> + </id> + <property type="System.Boolean" not-null="true" name="Active" column="[Active]" /> + <many-to-one name="Physician" cascade="none" column="PhysicianId" not-null="true" class="Physician" /> + <bag name="PatientRecords" inverse="true" lazy="true" cascade="all"> + <key column="PatientId" /> + <one-to-many class="PatientRecord" /> + </bag> + </class> + + <class name="Physician" table="Physicians"> + <id name="Id" column="PhysicianId" type="Int64"> + <generator class="native" /> + </id> + <property type="System.String" not-null="true" name="Name" column="[Name]" /> + </class> + + <class name="PatientRecord" table="PatientRecords"> + <id name="Id" column="PatientRecordId" type="System.Int64"> + <generator class="native" /> + </id> + <property type="NHibernate.Test.Linq.Entities.Gender, NHibernate.Test" not-null="true" name="Gender" column="[Gender]" /> + <property type="System.DateTime" not-null="true" name="BirthDate" column="[BirthDate]" /> + + <component name="Name" class="PatientName"> + <property type="System.String" not-null="true" name="FirstName" column="[FirstName]" /> + <property type="System.String" not-null="true" name="LastName" column="[LastName]" /> + </component> + + <component name="Address" class="PatientAddress"> + + <property type="System.String" name="AddressLine1" column="[AddressLine1]" /> + + <property type="System.String" name="AddressLine2" column="[AddressLine2]" /> + + <property type="System.String" name="City" column="[City]" /> + + <many-to-one name="State" cascade="none" column="StateId" class="State" /> + + <property type="System.String" name="ZipCode" column="[ZipCode]" /> + + </component> + + + <many-to-one name="Patient" cascade="none" column="PatientId" not-null="true" class="Patient" /> + </class> + + <class name="State" table="States"> + <id name="Id" column="StateId" type="System.Int64"> + <generator class="native" /> + </id> + <property type="System.String" not-null="true" name="Abbreviation" column="[Abbreviation]" /> + <property type="System.String" not-null="true" name="FullName" column="[FullName]" /> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/Linq/OrderByTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/OrderByTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/OrderByTests.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -0,0 +1,119 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class OrderByTests : LinqTestCase + { + [Test] + public void AscendingOrderByClause() + { + var query = from c in db.Customers + orderby c.CustomerId + select c.CustomerId; + + var ids = query.ToList(); + + if (ids.Count > 1) + { + Assert.Greater(ids[1], ids[0]); + } + } + + [Test] + public void DescendingOrderByClause() + { + var query = from c in db.Customers + orderby c.CustomerId descending + select c.CustomerId; + + var ids = query.ToList(); + + if (ids.Count > 1) + { + Assert.Greater(ids[0], ids[1]); + } + } + + [Test] + [Ignore("NHibernate does not currently support subqueries in select clause (no way to specify a projection from a detached criteria).")] + public void AggregateAscendingOrderByClause() + { + var query = from c in db.Customers + orderby c.Orders.Count + select c; + + var customers = query.ToList(); + + if (customers.Count > 1) + { + Assert.Less(customers[0].Orders.Count, customers[1].Orders.Count); + } + } + + [Test] + [Ignore("NHibernate does not currently support subqueries in select clause (no way to specify a projection from a detached criteria).")] + public void AggregateDescendingOrderByClause() + { + var query = from c in db.Customers + orderby c.Orders.Count descending + select c; + + var customers = query.ToList(); + + if (customers.Count > 1) + { + Assert.Greater(customers[0].Orders.Count, customers[1].Orders.Count); + } + } + + [Test] + public void ComplexAscendingOrderByClause() + { + var query = from c in db.Customers + where c.Address.Country == "Belgium" + orderby c.Address.Country, c.Address.City + select c.Address.City; + + var ids = query.ToList(); + + if (ids.Count > 1) + { + Assert.Greater(ids[1], ids[0]); + } + } + + [Test] + public void ComplexDescendingOrderByClause() + { + var query = from c in db.Customers + where c.Address.Country == "Belgium" + orderby c.Address.Country descending, c.Address.City descending + select c.Address.City; + + var ids = query.ToList(); + + if (ids.Count > 1) + { + Assert.Greater(ids[0], ids[1]); + } + } + + [Test] + public void ComplexAscendingDescendingOrderByClause() + { + var query = from c in db.Customers + where c.Address.Country == "Belgium" + orderby c.Address.Country ascending, c.Address.City descending + select c.Address.City; + + var ids = query.ToList(); + + if (ids.Count > 1) + { + Assert.Greater(ids[0], ids[1]); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/PagingTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/PagingTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/PagingTests.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -0,0 +1,63 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class PagingTests : LinqTestCase + { + [Test] + public void Customers1to5() + { + var q = (from c in db.Customers select c.CustomerId).Take(5); + var query = q.ToList(); + + Assert.AreEqual(5, query.Count); + } + + [Test] + public void Customers11to20() + { + var query = (from c in db.Customers + orderby c.CustomerId + select c.CustomerId).Skip(10).Take(10).ToList(); + Assert.AreEqual(query[0], "BSBEV"); + Assert.AreEqual(10, query.Count); + } + + [Test] + [Ignore("NHibernate does not currently support subqueries in from clause")] + public void CustomersChainedTake() + { + var q = (from c in db.Customers + orderby c.CustomerId + select c.CustomerId).Take(5).Take(6); + + var query = q.ToList(); + + Assert.AreEqual(5, query.Count); + Assert.AreEqual("ALFKI", query[0]); + Assert.AreEqual("BLAUS", query[4]); + } + + [Test] + [Ignore("NHibernate does not currently support subqueries in from clause")] + public void CustomersChainedSkip() + { + var q = (from c in db.Customers select c.CustomerId).Skip(10).Skip(5); + var query = q.ToList(); + Assert.AreEqual(query[0], "CONSH"); + Assert.AreEqual(76, query.Count); + } + + + + [Test] + [Ignore("NHibernate does not currently support subqueries in from clause")] + public void CountAfterTakeShouldReportTheCorrectNumber() + { + var users = db.Customers.Skip(3).Take(10); + Assert.AreEqual(10, users.Count()); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/PatientTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/PatientTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/PatientTests.cs 2009-11-25 21:46:06 UTC (rev 4859) @@ -0,0 +1,84 @@ +using System.Linq; +using NHibernate.Test.Linq.Entities; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class PatientTests : LinqTestCase + { + [Test] + public void CanQueryOnPropertyOfComponent() + { + var query = (from pr in db.PatientRecords + where pr.Name.LastName == "Doe" + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + + [Test] + public void CanQueryOnManyToOneOfComponent() + { + var florida = db.States.FirstOrDefault(x => x.Abbreviation == "FL"); + + var query = (from pr in db.PatientRecords + where pr.Address.State == florida + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + + [Test] + public void CanQueryOnPropertyOfManyToOneOfComponent() + { + var query = (from pr in db.PatientRecords + where pr.Address.State.Abbreviation == "FL" + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + + [Test] + public void CanQueryOnPropertyOfOneToMany() + { + var query = (from p in db.Patients + where p.PatientRecords.Any(x => x.Gender == Gender.Unknown) + select p).ToList(); + + Assert.AreEqual(1, query.Count); + } + + [Test] + public void CanQueryOnPropertyOfManyToOne() + { + var query = (from pr in db.PatientRecords + where pr.Patient.Active == true + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + + [Test] + public void CanQueryOnManyToOneOfManyToOne() + { + var drWatson = db.Physicians.FirstOrDefault(x => x.Name == "Dr Watson"); + + var query = (from pr in db.PatientRecords + where pr.Patient.Physician == drWatson + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + + [Test] + public void CanQueryOnPropertyOfManyToOneOfManyToOne() + { + var query = (from pr in db.PatientRecords + where pr.Patient.Physician.Name == "Dr Watson" + select pr).ToList(); + + Assert.AreEqual(2, query.Count); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-25 20:16:50 UTC (rev 4858) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-25 21:46:06 UTC (rev 4859) @@ -394,6 +394,7 @@ <Compile Include="Linq\Entities\Northwind.cs" /> <Compile Include="Linq\Entities\Order.cs" /> <Compile Include="Linq\Entities\OrderLine.cs" /> + <Compile Include="Linq\Entities\Patient.cs" /> <Compile Include="Linq\Entities\Product.cs" /> <Compile Include="Linq\Entities\ProductCategory.cs" /> <Compile Include="Linq\Entities\Region.cs" /> @@ -412,7 +413,10 @@ <Compile Include="Linq\MethodCallTests.cs" /> <Compile Include="Linq\MiscellaneousTextFixture.cs" /> <Compile Include="Linq\ObjectDumper.cs" /> + <Compile Include="Linq\OrderByTests.cs" /> + <Compile Include="Linq\PagingTests.cs" /> <Compile Include="Linq\ParameterisedQueries.cs" /> + <Compile Include="Linq\PatientTests.cs" /> <Compile Include="Linq\ReadonlyTestCase.cs" /> <Compile Include="MappingTest\NonReflectiveBinderFixture.cs" /> <Compile Include="MappingTest\Wicked.cs" /> @@ -2081,6 +2085,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="Linq\Mappings\Patient.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2011\Mappings.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\Animal.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\AnotherEntity.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2009-11-25 20:17:08
|
Revision: 4858 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4858&view=rev Author: steverstrong Date: 2009-11-25 20:16:50 +0000 (Wed, 25 Nov 2009) Log Message: ----------- Added additional Linq tests and upgraded to latest re-linq trunk Modified Paths: -------------- trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll trunk/nhibernate/lib/net/3.5/Remotion.Interfaces.dll trunk/nhibernate/lib/net/3.5/Remotion.dll trunk/nhibernate/src/NHibernate/IQueryExpression.cs trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Linq/MethodCallTests.cs trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Impl/ExpressionQueryImpl.cs trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs Modified: trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll =================================================================== (Binary files differ) Modified: trunk/nhibernate/lib/net/3.5/Remotion.Interfaces.dll =================================================================== (Binary files differ) Modified: trunk/nhibernate/lib/net/3.5/Remotion.dll =================================================================== (Binary files differ) Modified: trunk/nhibernate/src/NHibernate/IQueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryExpression.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/IQueryExpression.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -11,6 +11,5 @@ string Key { get; } System.Type Type { get; } IList<NamedParameterDescriptor> ParameterDescriptors { get; } - void SetQueryPropertiesPriorToExecute(IQuery impl); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -258,8 +258,8 @@ using (new SessionIdLoggingContext(SessionId)) { CheckAndUpdateSessionStatus(); - HQLQueryPlan queryPlan = GetHQLQueryPlan(queryExpression, false); - QueryImpl query = new QueryImpl(queryPlan.QueryExpression, + var queryPlan = GetHQLQueryPlan(queryExpression, false); + var query = new ExpressionQueryImpl(queryPlan.QueryExpression, this, queryPlan.ParameterMetadata ); Added: trunk/nhibernate/src/NHibernate/Impl/ExpressionQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionQueryImpl.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionQueryImpl.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using NHibernate.Engine; +using NHibernate.Engine.Query; + +namespace NHibernate.Impl +{ + class ExpressionQueryImpl : AbstractQueryImpl + { + private readonly Dictionary<string, LockMode> _lockModes = new Dictionary<string, LockMode>(2); + + public IQueryExpression QueryExpression { get; private set; } + + public ExpressionQueryImpl(IQueryExpression queryExpression, ISessionImplementor session, ParameterMetadata parameterMetadata) + : base(queryExpression.Key, FlushMode.Unspecified, session, parameterMetadata) + { + QueryExpression = queryExpression; + } + + public override IQuery SetLockMode(string alias, LockMode lockMode) + { + _lockModes[alias] = lockMode; + return this; + } + + protected internal override IDictionary<string, LockMode> LockModes + { + get { return _lockModes; } + } + + public override int ExecuteUpdate() + { + throw new NotImplementedException(); + } + + public override IEnumerable Enumerable() + { + throw new NotImplementedException(); + } + + public override IEnumerable<T> Enumerable<T>() + { + throw new NotImplementedException(); + } + + public override IList List() + { + VerifyParameters(); + IDictionary<string, TypedValue> namedParams = NamedParams; + Before(); + try + { + return Session.List(QueryExpression, GetQueryParameters(namedParams)); + } + finally + { + After(); + } + } + + public override void List(IList results) + { + throw new NotImplementedException(); + } + + public override IList<T> List<T>() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -13,7 +13,6 @@ public class QueryImpl : AbstractQueryImpl { private readonly Dictionary<string, LockMode> lockModes = new Dictionary<string, LockMode>(2); - private readonly IQueryExpression _queryExpression; public QueryImpl(string queryString, FlushMode flushMode, ISessionImplementor session, ParameterMetadata parameterMetadata) : base(queryString, flushMode, session, parameterMetadata) @@ -25,12 +24,6 @@ { } - public QueryImpl(IQueryExpression queryExpression, ISessionImplementor session, ParameterMetadata parameterMetadata) - : base(queryExpression.Key, FlushMode.Unspecified, session, parameterMetadata) - { - _queryExpression = queryExpression; - } - public override IEnumerable Enumerable() { VerifyParameters(); @@ -68,15 +61,7 @@ Before(); try { - if (_queryExpression == null) - { - return Session.List(ExpandParameterLists(namedParams), GetQueryParameters(namedParams)); - } - else - { - _queryExpression.SetQueryPropertiesPriorToExecute(this); - return Session.List(_queryExpression, GetQueryParameters(namedParams)); - } + return Session.List(ExpandParameterLists(namedParams), GetQueryParameters(namedParams)); } finally { Added: trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using NHibernate.Hql.Ast; + +namespace NHibernate.Linq +{ + public class ExpressionToHqlTranslationResults + { + public HqlQuery Statement { get; private set; } + public ResultTransformer ResultTransformer { get; private set; } + public List<Action<IQuery, IDictionary<string, object>>> AdditionalCriteria { get; private set; } + + public ExpressionToHqlTranslationResults(HqlQuery statement, IList<LambdaExpression> itemTransformers, IList<LambdaExpression> listTransformers, List<Action<IQuery, IDictionary<string, object>>> additionalCriteria) + { + Statement = statement; + + var itemTransformer = MergeLambdas(itemTransformers); + var listTransformer = MergeLambdas(listTransformers); + + if (itemTransformer != null || listTransformer != null) + { + ResultTransformer = new ResultTransformer(itemTransformer, listTransformer); + } + + AdditionalCriteria = additionalCriteria; + } + + private static LambdaExpression MergeLambdas(IList<LambdaExpression> transformations) + { + if (transformations == null || transformations.Count == 0) + { + return null; + } + + var listTransformLambda = transformations[0]; + + for (int i = 1; i < transformations.Count; i++) + { + var invoked = Expression.Invoke(transformations[i], listTransformLambda.Body); + + listTransformLambda = Expression.Lambda(invoked, listTransformLambda.Parameters.ToArray()); + } + + return listTransformLambda; + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -6,6 +6,7 @@ using NHibernate.Hql.Ast.ANTLR.Tree; using NHibernate.Linq.ResultOperators; using NHibernate.Linq.Visitors; +using Remotion.Data.Linq; using Remotion.Data.Linq.Clauses; using Remotion.Data.Linq.Clauses.StreamedData; using Remotion.Data.Linq.Parsing.ExpressionTreeVisitors; @@ -16,24 +17,20 @@ { public class NhLinqExpression : IQueryExpression { - private static readonly MethodCallExpressionNodeTypeRegistry MethodCallRegistry = - MethodCallExpressionNodeTypeRegistry.CreateDefault(); + public string Key { get; private set; } - static NhLinqExpression() - { - MethodCallRegistry.Register( - new[] - { - MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object>(null, null))), - MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object, object>(null, null, null))) - }, - typeof (AggregateExpressionNode)); - } + public System.Type Type { get; private set; } + public IList<NamedParameterDescriptor> ParameterDescriptors { get; private set; } + public NhLinqExpressionReturnType ReturnType { get; private set; } + + public IDictionary<string, object> ParameterValuesByName { get; private set; } + + public ExpressionToHqlTranslationResults ExpressionToHqlTranslationResults { get; private set; } + private readonly Expression _expression; - private CommandData _commandData; - private readonly IDictionary<ConstantExpression, NamedParameter> _queryParameters; + private readonly IDictionary<ConstantExpression, NamedParameter> _constantToParameterMap; public NhLinqExpression(Expression expression) { @@ -41,13 +38,13 @@ _expression = NameUnNamedParameters.Visit(_expression); - _queryParameters = ExpressionParameterVisitor.Visit(_expression); - ParameterValuesByName = _queryParameters.Values.ToDictionary(p => p.Name, p => p.Value); + _constantToParameterMap = ExpressionParameterVisitor.Visit(_expression); - Key = ExpressionKeyVisitor.Visit(_expression, _queryParameters); - Type = _expression.Type; + ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name, p => p.Value); - ParameterValues = _queryParameters.Values; + Key = ExpressionKeyVisitor.Visit(_expression, _constantToParameterMap); + + Type = _expression.Type; // Note - re-linq handles return types via the GetOutputDataInfo method, and allows for SingleOrDefault here for the ChoiceResultOperator... ReturnType = NhLinqExpressionReturnType.Scalar; @@ -64,34 +61,38 @@ var requiredHqlParameters = new List<NamedParameterDescriptor>(); // TODO - can we cache any of this? - var queryModel = new QueryParser(new ExpressionTreeParser(MethodCallRegistry)).GetParsedQuery(_expression); + var queryModel = NhRelinqQueryParser.Parse(_expression); - _commandData = QueryModelVisitor.GenerateHqlQuery(queryModel, _queryParameters, requiredHqlParameters); + ExpressionToHqlTranslationResults = QueryModelVisitor.GenerateHqlQuery(queryModel, _constantToParameterMap, requiredHqlParameters); ParameterDescriptors = requiredHqlParameters.AsReadOnly(); - return _commandData.Statement.AstNode; + return ExpressionToHqlTranslationResults.Statement.AstNode; } + } - public string Key { get; private set; } + public static class NhRelinqQueryParser + { + public static readonly MethodCallExpressionNodeTypeRegistry MethodCallRegistry = + MethodCallExpressionNodeTypeRegistry.CreateDefault(); - public IList<NamedParameterDescriptor> ParameterDescriptors { get; private set; } + static NhRelinqQueryParser() + { + MethodCallRegistry.Register( + new[] + { + MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object>(null, null))), + MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object, object>(null, null, null))) + }, + typeof (AggregateExpressionNode)); + } - public ICollection<NamedParameter> ParameterValues { get; private set; } + public static QueryModel Parse(Expression expression) + { + return new QueryParser(new ExpressionTreeParser(MethodCallRegistry)).GetParsedQuery(expression); + } + } - public NhLinqExpressionReturnType ReturnType { get; private set; } - - public System.Type Type { get; private set; } - - public IDictionary<string, object> ParameterValuesByName { get; private set; } - - public void SetQueryPropertiesPriorToExecute(IQuery impl) - { - _commandData.SetResultTransformer(impl); - _commandData.AddAdditionalCriteria(impl); - } - } - public class NameUnNamedParameters : NhExpressionTreeVisitor { public static Expression Visit(Expression expression) Modified: trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using NHibernate.Impl; namespace NHibernate.Linq { @@ -21,6 +22,7 @@ var query = _session.CreateQuery(nhLinqExpression); SetParameters(query, nhLinqExpression.ParameterValuesByName); + SetResultTransformerAndAdditionalCriteria(query, nhLinqExpression.ParameterValuesByName); var results = query.List(); @@ -56,5 +58,19 @@ query.SetParameter(parameterName, parameters[parameterName]); } } + + public void SetResultTransformerAndAdditionalCriteria(IQuery query, IDictionary<string, object> parameters) + { + var queryImpl = (ExpressionQueryImpl) query; + + var nhExpression = (NhLinqExpression) queryImpl.QueryExpression; + + query.SetResultTransformer(nhExpression.ExpressionToHqlTranslationResults.ResultTransformer); + + foreach (var criteria in nhExpression.ExpressionToHqlTranslationResults.AdditionalCriteria) + { + criteria(query, parameters); + } + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -0,0 +1,36 @@ +using System; +using System.Linq; +using Remotion.Data.Linq; +using Remotion.Data.Linq.Clauses; +using Remotion.Data.Linq.Clauses.ResultOperators; + +namespace NHibernate.Linq.ReWriters +{ + public class RemoveUnnecessaryBodyOperators : QueryModelVisitorBase + { + private RemoveUnnecessaryBodyOperators() + { + } + + public static void ReWrite(QueryModel queryModel) + { + var rewriter = new RemoveUnnecessaryBodyOperators(); + + rewriter.VisitQueryModel(queryModel); + } + + public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index) + { + if (resultOperator is CountResultOperator) + { + // For count operators, we can remove any order-by result operators + foreach (var orderby in queryModel.BodyClauses.Where(bc => bc is OrderByClause).ToList()) + { + queryModel.BodyClauses.Remove(orderby); + } + } + + base.VisitResultOperator(resultOperator, queryModel, index); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -15,12 +15,12 @@ /// </summary> public class ExpressionKeyVisitor : ExpressionTreeVisitor { - private readonly IDictionary<ConstantExpression, NamedParameter> _parameters; + private readonly IDictionary<ConstantExpression, NamedParameter> _constantToParameterMap; readonly StringBuilder _string = new StringBuilder(); - private ExpressionKeyVisitor(IDictionary<ConstantExpression, NamedParameter> parameters) + private ExpressionKeyVisitor(IDictionary<ConstantExpression, NamedParameter> constantToParameterMap) { - _parameters = parameters; + _constantToParameterMap = constantToParameterMap; } public static string Visit(Expression expression, IDictionary<ConstantExpression, NamedParameter> parameters) @@ -76,7 +76,7 @@ { NamedParameter param; - if (_parameters.TryGetValue(expression, out param)) + if (_constantToParameterMap.TryGetValue(expression, out param)) { _string.Append(param.Name); } Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -353,7 +353,7 @@ protected HqlTreeNode VisitSubQueryExpression(SubQueryExpression expression) { - CommandData query = QueryModelVisitor.GenerateHqlQuery(expression.QueryModel, _parameters, _requiredHqlParameters); + ExpressionToHqlTranslationResults query = QueryModelVisitor.GenerateHqlQuery(expression.QueryModel, _parameters, _requiredHqlParameters); return query.Statement; } Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -18,8 +18,11 @@ { public class QueryModelVisitor : QueryModelVisitorBase { - public static CommandData GenerateHqlQuery(QueryModel queryModel, IDictionary<ConstantExpression, NamedParameter> parameters, IList<NamedParameterDescriptor> requiredHqlParameters) + public static ExpressionToHqlTranslationResults GenerateHqlQuery(QueryModel queryModel, IDictionary<ConstantExpression, NamedParameter> parameters, IList<NamedParameterDescriptor> requiredHqlParameters) { + // Remove unnecessary body operators + RemoveUnnecessaryBodyOperators.ReWrite(queryModel); + // Merge aggregating result operators (distinct, count, sum etc) into the select clause MergeAggregatingResultsRewriter.ReWrite(queryModel); @@ -41,12 +44,12 @@ var visitor = new QueryModelVisitor(parameters, requiredHqlParameters); visitor.VisitQueryModel(queryModel); - return visitor.GetHqlCommand(); + return visitor.GetTranslation(); } private readonly HqlTreeBuilder _hqlTreeBuilder; - private readonly List<Action<IQuery>> _additionalCriteria = new List<Action<IQuery>>(); + private readonly List<Action<IQuery, IDictionary<string, object>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, object>>>(); private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>(); private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>(); @@ -66,7 +69,8 @@ _requiredHqlParameters = requiredHqlParameters; _hqlTreeBuilder = new HqlTreeBuilder(); } - public CommandData GetHqlCommand() + + public ExpressionToHqlTranslationResults GetTranslation() { HqlSelectFrom selectFrom = _hqlTreeBuilder.SelectFrom(); @@ -104,10 +108,10 @@ query.AddChild(_orderByClause); } - return new CommandData(query, - _itemTransformers, - _listTransformers, - _additionalCriteria); + return new ExpressionToHqlTranslationResults(query, + _itemTransformers, + _listTransformers, + _additionalCriteria); } private HqlBooleanExpression MergeWhereClauses() @@ -297,14 +301,34 @@ private void ProcessTakeOperator(TakeResultOperator resultOperator) { - _additionalCriteria.Add(q => q.SetMaxResults(resultOperator.GetConstantCount())); + NamedParameter parameterName; + + // TODO - very similar to ProcessSkip, plus want to investigate the scenario in the "else" + // clause to see if it is valid + if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) + { + _additionalCriteria.Add((q, p) => q.SetMaxResults((int) p[parameterName.Name])); + } + else + { + _additionalCriteria.Add((q, p) => q.SetMaxResults(resultOperator.GetConstantCount())); + } } private void ProcessSkipOperator(SkipResultOperator resultOperator) { - _additionalCriteria.Add(q => q.SetFirstResult(resultOperator.GetConstantCount())); - } + NamedParameter parameterName; + if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) + { + _additionalCriteria.Add((q, p) => q.SetFirstResult((int)p[parameterName.Name])); + } + else + { + _additionalCriteria.Add((q, p) => q.SetFirstResult(resultOperator.GetConstantCount())); + } + } + private void ProcessNonAggregatingGroupBy(NonAggregatingGroupBy resultOperator, QueryModel model) { var tSource = model.SelectClause.Selector.Type; @@ -394,7 +418,7 @@ private void ProcessFirstOperator() { - _additionalCriteria.Add(q => q.SetMaxResults(1)); + _additionalCriteria.Add((q, p) => q.SetMaxResults(1)); } private static bool CanBeEvaluatedInHqlSelectStatement(Expression expression) Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-25 20:16:50 UTC (rev 4858) @@ -586,6 +586,7 @@ <Compile Include="Linq\Expressions\NhMaxExpression.cs" /> <Compile Include="Linq\Expressions\NhMinExpression.cs" /> <Compile Include="Linq\Expressions\NhSumExpression.cs" /> + <Compile Include="Impl\ExpressionQueryImpl.cs" /> <Compile Include="Linq\Visitors\IHqlExpressionVisitor.cs" /> <Compile Include="Linq\GroupJoin\IsAggregatingResults.cs" /> <Compile Include="Linq\GroupJoin\GroupJoinAggregateDetectionVisitor.cs" /> @@ -602,6 +603,7 @@ <Compile Include="Linq\Functions\DateTimeGenerator.cs" /> <Compile Include="Linq\Functions\StringGenerator.cs" /> <Compile Include="Linq\Functions\QueryableGenerator.cs" /> + <Compile Include="Linq\ReWriters\RemoveUnnecessaryBodyOperators.cs" /> <Compile Include="Linq\Visitors\SwapQuerySourceVisitor.cs" /> <Compile Include="Linq\Visitors\EqualityHqlGenerator.cs" /> <Compile Include="Linq\Visitors\ExpressionParameterVisitor.cs" /> @@ -613,7 +615,7 @@ <Compile Include="Linq\GroupBy\AggregatingGroupByRewriter.cs" /> <Compile Include="Linq\GroupJoin\AggregatingGroupJoinRewriter.cs" /> <Compile Include="Linq\ResultOperators\ClientSideTransformOperator.cs" /> - <Compile Include="Linq\CommandData.cs" /> + <Compile Include="Linq\ExpressionToHqlTranslationResults.cs" /> <Compile Include="Linq\EnumerableHelper.cs" /> <Compile Include="Linq\GroupBy\GroupBySelectClauseRewriter.cs" /> <Compile Include="Linq\Visitors\GroupByKeySelectorVisitor.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/Linq/MethodCallTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/MethodCallTests.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate.Test/Linq/MethodCallTests.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -4,10 +4,10 @@ namespace NHibernate.Test.Linq { [TestFixture] - [Ignore] public class MethodCallTests : LinqTestCase { [Test] + [Ignore("Waiting for re-linq support")] public void CanExecuteAny() { bool result = db.Users.Any(); @@ -15,7 +15,8 @@ } [Test] - public void CanExecuteAnyWithArguments() + [Ignore("Waiting for re-linq support")] + public void CanExecuteAnyWithArguments() { bool result = db.Users.Any(u => u.Name == "user-does-not-exist"); Assert.IsFalse(result); Modified: trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -1,5 +1,7 @@ using System; using System.Linq; +using System.Linq.Expressions; +using NHibernate.Test.Linq.Entities; using NUnit.Framework; namespace NHibernate.Test.Linq @@ -29,5 +31,71 @@ Console.WriteLine(count); } + + [Category("From NHUser list")] + [Test(Description = "Telerik grid example, http://www.telerik.com/community/forums/aspnet-mvc/grid/grid-and-nhibernate-linq.aspx")] + public void TelerikGridWhereClause() + { + Expression<Func<Customer, bool>> filter = c => c.ContactName.ToLower().StartsWith("a"); + IQueryable<Customer> value = db.Customers; + + var results = value.Where(filter).ToList(); + + Assert.IsFalse(results.Where(c => !c.ContactName.ToLower().StartsWith("a")).Any()); + } + + [Category("From NHUser list")] + [Test(Description = "Predicated count on a child list")] + public void PredicatedCountOnChildList() + { + var results = (from c in db.Customers + select new + { + c.ContactName, + Count = c.Orders.Count(o => o.Employee.EmployeeId == 4) + }).ToList(); + + Assert.AreEqual(91, results.Count()); + Assert.AreEqual(2, results.Where(c => c.ContactName == "Maria Anders").Single().Count); + Assert.AreEqual(4, results.Where(c => c.ContactName == "Thomas Hardy").Single().Count); + Assert.AreEqual(0, results.Where(c => c.ContactName == "Elizabeth Brown").Single().Count); + } + + [Category("From NHUser list")] + [Test(Description = "Reference an outer object in a predicate")] + public void ReferenceToOuter() + { + var results = from c in db.Customers + where + c.Orders.Any(o => o.ShippedTo == c.CompanyName) + select c; + + Assert.AreEqual(85, results.Count()); + } + + [Category("Paging")] + [Test(Description = "This sample uses a where clause and the Skip and Take operators to select " + + "the second, third and fourth pages of products")] + public void TriplePageSelection() + { + IQueryable<Product> q = ( + from p in db.Products + where p.ProductId > 1 + orderby p.ProductId + select p + ); + + IQueryable<Product> page2 = q.Skip(5).Take(5); + IQueryable<Product> page3 = q.Skip(10).Take(5); + IQueryable<Product> page4 = q.Skip(15).Take(5); + + var firstResultOnPage2 = page2.First(); + var firstResultOnPage3 = page3.First(); + var firstResultOnPage4 = page4.First(); + + Assert.AreNotEqual(firstResultOnPage2.ProductId, firstResultOnPage3.ProductId); + Assert.AreNotEqual(firstResultOnPage3.ProductId, firstResultOnPage4.ProductId); + Assert.AreNotEqual(firstResultOnPage2.ProductId, firstResultOnPage4.ProductId); + } } } Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-25 18:36:07 UTC (rev 4857) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-25 20:16:50 UTC (rev 4858) @@ -48,10 +48,10 @@ var nhNewYork = new NhLinqExpression(newYork.Body); Assert.AreEqual(nhLondon.Key, nhNewYork.Key); - Assert.AreEqual(1, nhLondon.ParameterValues.Count); - Assert.AreEqual(1, nhNewYork.ParameterValues.Count); - Assert.AreEqual("London", nhLondon.ParameterValues.First().Value); - Assert.AreEqual("New York", nhNewYork.ParameterValues.First().Value); + Assert.AreEqual(1, nhLondon.ParameterValuesByName.Count); + Assert.AreEqual(1, nhNewYork.ParameterValuesByName.Count); + Assert.AreEqual("London", nhLondon.ParameterValuesByName.First().Value); + Assert.AreEqual("New York", nhNewYork.ParameterValuesByName.First().Value); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-25 18:36:17
|
Revision: 4857 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4857&view=rev Author: ricbrown Date: 2009-11-25 18:36:07 +0000 (Wed, 25 Nov 2009) Log Message: ----------- Added typed inline projections to QueryOver. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -0,0 +1,223 @@ + +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +using NHibernate.Impl; +using NHibernate.SqlCommand; + +namespace NHibernate.Criterion.Lambda +{ + + public class QueryOverProjectionBuilder<R, T> + { + + private R fluentReturn; + private IQueryOver<T> criteria; + private ProjectionList projectionList; + private IProjection lastProjection = null; + + public QueryOverProjectionBuilder(R fluentReturn, IQueryOver<T> criteria) + { + this.fluentReturn = fluentReturn; + this.criteria = criteria; + projectionList = Projections.ProjectionList(); + } + + private void AddLastProjection() + { + if (lastProjection != null) + projectionList.Add(lastProjection); + } + + private void PushProjection(IProjection projection) + { + AddLastProjection(); + lastProjection = projection; + } + + /// <summary> + /// Create the ProjectionList and return to the query + /// </summary> + public R EndSelect + { + get + { + AddLastProjection(); + criteria.Select(projectionList); + return fluentReturn; + } + } + + /// <summary> + /// Create an alias for the previous projection + /// </summary> + public QueryOverProjectionBuilder<R, T> WithAlias(Expression<Func<object>> alias) + { + string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body); + lastProjection = Projections.Alias(lastProjection, aliasContainer); + return this; + } + + /// <summary> + /// Select an arbitrary projection + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(IProjection projection) + { + PushProjection(projection); + return this; + } + + /// <summary> + /// A property average value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Avg(expression)); + return this; + } + + /// <summary> + /// A property average value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<object>> expression) + { + PushProjection(Projections.Avg(expression)); + return this; + } + + /// <summary> + /// A property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Count(expression)); + return this; + } + + /// <summary> + /// A property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<object>> expression) + { + PushProjection(Projections.Count(expression)); + return this; + } + + /// <summary> + /// A distinct property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<T, object>> expression) + { + PushProjection(Projections.CountDistinct(expression)); + return this; + } + + /// <summary> + /// A distinct property value count + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<object>> expression) + { + PushProjection(Projections.CountDistinct(expression)); + return this; + } + + /// <summary> + /// A grouping property value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Group(expression)); + return this; + } + + /// <summary> + /// A grouping property value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<object>> expression) + { + PushProjection(Projections.Group(expression)); + return this; + } + + /// <summary> + /// A property maximum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Max(expression)); + return this; + } + + /// <summary> + /// A property maximum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<object>> expression) + { + PushProjection(Projections.Max(expression)); + return this; + } + + /// <summary> + /// A property minimum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Min(expression)); + return this; + } + + /// <summary> + /// A property minimum value + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<object>> expression) + { + PushProjection(Projections.Min(expression)); + return this; + } + + /// <summary> + /// A projected property value + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Property(expression)); + return this; + } + + /// <summary> + /// A projected property value + /// </summary> + public QueryOverProjectionBuilder<R, T> Select(Expression<Func<object>> expression) + { + PushProjection(Projections.Property(expression)); + return this; + } + + public QueryOverProjectionBuilder<R, T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver) + { + PushProjection(Projections.SubQuery(detachedQueryOver)); + return this; + } + + /// <summary> + /// A property value sum + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<T, object>> expression) + { + PushProjection(Projections.Sum(expression)); + return this; + } + + /// <summary> + /// A property value sum + /// </summary> + public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<object>> expression) + { + PushProjection(Projections.Sum(expression)); + return this; + } + + } + +} Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -370,7 +370,7 @@ /// <summary> /// A grouping property value /// </summary> - public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> expression) + public static PropertyProjection Group<T>(Expression<Func<T, object>> expression) { return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); } @@ -378,7 +378,7 @@ /// <summary> /// A grouping property value /// </summary> - public static PropertyProjection GroupProperty(Expression<Func<object>> expression) + public static PropertyProjection Group(Expression<Func<object>> expression) { return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); } Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -171,6 +171,11 @@ return this; } + QueryOverProjectionBuilder<QueryOver<T>, T> SelectList + { + get { return new QueryOverProjectionBuilder<QueryOver<T>, T>(this, this); } + } + public QueryOverOrderBuilder<T> OrderBy(Expression<Func<T, object>> path) { return new QueryOverOrderBuilder<T>(this, path); @@ -558,6 +563,9 @@ IQueryOver<T> IQueryOver<T>.Select(params IProjection[] projections) { return Select(projections); } + QueryOverProjectionBuilder<IQueryOver<T>, T> IQueryOver<T>.SelectList + { get { return new QueryOverProjectionBuilder<IQueryOver<T>,T>(this, this); } } + IQueryOverOrderBuilder<T> IQueryOver<T>.OrderBy(Expression<Func<T, object>> path) { return new IQueryOverOrderBuilder<T>(this, path); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -137,6 +137,11 @@ IQueryOver<T> Select(params IProjection[] projections); /// <summary> + /// Create a list of projections inline + /// </summary> + QueryOverProjectionBuilder<IQueryOver<T>, T> SelectList { get; } + + /// <summary> /// Add order expressed as a lambda expression /// </summary> /// <param name="path">Lambda expression</param> Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-25 18:36:07 UTC (rev 4857) @@ -512,6 +512,7 @@ <Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverLockBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverOrderBuilder.cs" /> + <Compile Include="Criterion\Lambda\QueryOverProjectionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-25 18:36:07 UTC (rev 4857) @@ -70,8 +70,8 @@ .Add(Projections.Count(() => personAlias.Age)) .Add(Projections.CountDistinct<Person>(p => p.Age)) .Add(Projections.CountDistinct(() => personAlias.Age)) - .Add(Projections.GroupProperty<Person>(p => p.Age)) - .Add(Projections.GroupProperty(() => personAlias.Age)) + .Add(Projections.Group<Person>(p => p.Age)) + .Add(Projections.Group(() => personAlias.Age)) .Add(Projections.Max<Person>(p => p.Age)) .Add(Projections.Max(() => personAlias.Age)) .Add(Projections.Min<Person>(p => p.Age)) @@ -85,6 +85,59 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void InlineProjectionList() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .SetProjection(Projections.ProjectionList() + .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias")) + .Add(Projections.Avg("Age")) + .Add(Projections.Avg("personAlias.Age")) + .Add(Projections.Count("Age")) + .Add(Projections.Count("personAlias.Age")) + .Add(Projections.CountDistinct("Age")) + .Add(Projections.CountDistinct("personAlias.Age")) + .Add(Projections.GroupProperty("Age")) + .Add(Projections.GroupProperty("personAlias.Age")) + .Add(Projections.Max("Age")) + .Add(Projections.Max("personAlias.Age")) + .Add(Projections.Min("Age")) + .Add(Projections.Min("personAlias.Age")) + .Add(Projections.Property("Age")) + .Add(Projections.Property("personAlias.Age")) + .Add(Projections.SubQuery(DetachedCriteriaAge)) + .Add(Projections.Sum("Age")) + .Add(Projections.Sum("personAlias.Age"))); + + Person personAlias = null; + Person personAgeProjectionAlias = null; + var actual = + CreateTestQueryOver<Person>(() => personAlias) + .SelectList + .SelectAvg(p => p.Age).WithAlias(() => personAgeProjectionAlias) + .Select(Projections.Avg("Age")) // allows private properties + .SelectAvg(() => personAlias.Age) + .SelectCount(p => p.Age) + .SelectCount(() => personAlias.Age) + .SelectCountDistinct(p => p.Age) + .SelectCountDistinct(() => personAlias.Age) + .SelectGroup(p => p.Age) + .SelectGroup(() => personAlias.Age) + .SelectMax(p => p.Age) + .SelectMax(() => personAlias.Age) + .SelectMin(p => p.Age) + .SelectMin(() => personAlias.Age) + .Select(p => p.Age) + .Select(() => personAlias.Age) + .SelectSubQuery(DetachedQueryOverAge) + .SelectSum(p => p.Age) + .SelectSum(() => personAlias.Age) + .EndSelect; + + AssertCriteriaAreEqual(expected, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-23 18:00:28
|
Revision: 4856 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4856&view=rev Author: ricbrown Date: 2009-11-23 18:00:21 +0000 (Mon, 23 Nov 2009) Log Message: ----------- Moved creation of detached QueryOver of T to a factory method. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -19,6 +19,16 @@ protected QueryOver() { } + public static QueryOver<T> Of<T>() + { + return new QueryOver<T>(); + } + + public static QueryOver<T> Of<T>(Expression<Func<T>> alias) + { + return new QueryOver<T>(alias); + } + public ICriteria UnderlyingCriteria { get { return _criteria; } @@ -38,13 +48,13 @@ public class QueryOver<T> : QueryOver, IQueryOver<T> { - public QueryOver() + protected internal QueryOver() { _impl = new CriteriaImpl(typeof(T), null); _criteria = _impl; } - public QueryOver(Expression<Func<T>> alias) + protected internal QueryOver(Expression<Func<T>> alias) { string aliasPath = ExpressionProcessor.FindMemberExpression(alias.Body); _impl = new CriteriaImpl(typeof(T), aliasPath, null); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -81,7 +81,7 @@ using (ISession s = OpenSession()) { QueryOver<Person> personQuery = - new QueryOver<Person>() + QueryOver.Of<Person>() .Where(p => p.Name == "test person 1"); IList<Person> actual = Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -27,7 +27,7 @@ get { return - new QueryOver<Child>(() => _subqueryChildAlias) + QueryOver.Of<Child>(() => _subqueryChildAlias) .Where(() => _subqueryChildAlias.Nickname == "subquery name") .Select(p => p.Age); } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -477,7 +477,7 @@ Person personAlias = null; QueryOver<Person> actual = - new QueryOver<Person>(() => personAlias) + QueryOver.Of<Person>(() => personAlias) .Where(() => personAlias.Name == "test name"); AssertCriteriaAreEqual(expected, actual); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -158,7 +158,7 @@ Person personAlias = null; QueryOver<Person> actual = - new QueryOver<Person>(() => personAlias) + QueryOver.Of<Person>(() => personAlias) .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65) .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65) .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" }) Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-23 18:00:21 UTC (rev 4856) @@ -47,7 +47,7 @@ get { return - new QueryOver<Child>(() => _subqueryChildAlias) + QueryOver.Of<Child>(() => _subqueryChildAlias) .Where(() => _subqueryChildAlias.Nickname == "subquery name"); } } @@ -57,7 +57,7 @@ get { return - new QueryOver<Child>(() => _subqueryChildAlias) + QueryOver.Of<Child>(() => _subqueryChildAlias) .Where(() => _subqueryChildAlias.Nickname == "subquery name") .Select(p => p.Nickname); } @@ -68,7 +68,7 @@ get { return - new QueryOver<Child>(() => _subqueryChildAlias) + QueryOver.Of<Child>(() => _subqueryChildAlias) .Where(() => _subqueryChildAlias.Nickname == "subquery name") .Select(p => p.Age); } @@ -112,7 +112,7 @@ Person personAlias = null; QueryOver<Person> actual = - new QueryOver<Person>(() => personAlias) + QueryOver.Of<Person>(() => personAlias) .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName) .WithSubquery.WhereProperty(() => personAlias.Name).Eq(DetachedQueryOverName); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-23 17:38:18
|
Revision: 4855 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4855&view=rev Author: ricbrown Date: 2009-11-23 17:38:07 +0000 (Mon, 23 Nov 2009) Log Message: ----------- Added first cut of projections using Lambda expressions. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs trunk/nhibernate/src/NHibernate/Criterion/Projections.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2009-11-22 15:34:59 UTC (rev 4854) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2009-11-23 17:38:07 UTC (rev 4855) @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using NHibernate.Impl; using NHibernate.SqlCommand; using NHibernate.Type; -using System.Collections.Generic; namespace NHibernate.Criterion { @@ -32,6 +34,11 @@ return Add(Projections.Alias(projection, alias)); } + public ProjectionList Add<T>(IProjection projection, Expression<Func<T>> alias) + { + return Add(projection, ExpressionProcessor.FindMemberExpression(alias.Body)); + } + public IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery) { IList<IType> types = new List<IType>(Length); Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-22 15:34:59 UTC (rev 4854) +++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-23 17:38:07 UTC (rev 4855) @@ -1,4 +1,6 @@ using System; +using System.Linq.Expressions; +using NHibernate.Impl; using NHibernate.Type; namespace NHibernate.Criterion @@ -316,5 +318,138 @@ SelectSubqueryExpression expr = new SelectSubqueryExpression(detachedCriteria); return new SubqueryProjection(expr); } + + /// <summary> + /// A property average value + /// </summary> + public static AggregateProjection Avg<T>(Expression<Func<T, object>> expression) + { + return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property average value + /// </summary> + public static AggregateProjection Avg(Expression<Func<object>> expression) + { + return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property value count + /// </summary> + public static CountProjection Count<T>(Expression<Func<T, object>> expression) + { + return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property value count + /// </summary> + public static CountProjection Count(Expression<Func<object>> expression) + { + return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A distinct property value count + /// </summary> + public static CountProjection CountDistinct<T>(Expression<Func<T, object>> expression) + { + return Projections.CountDistinct(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A distinct property value count + /// </summary> + public static CountProjection CountDistinct(Expression<Func<object>> expression) + { + return Projections.CountDistinct(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A grouping property value + /// </summary> + public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> expression) + { + return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A grouping property value + /// </summary> + public static PropertyProjection GroupProperty(Expression<Func<object>> expression) + { + return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property maximum value + /// </summary> + public static AggregateProjection Max<T>(Expression<Func<T, object>> expression) + { + return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property maximum value + /// </summary> + public static AggregateProjection Max(Expression<Func<object>> expression) + { + return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property minimum value + /// </summary> + public static AggregateProjection Min<T>(Expression<Func<T, object>> expression) + { + return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property minimum value + /// </summary> + public static AggregateProjection Min(Expression<Func<object>> expression) + { + return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A projected property value + /// </summary> + public static PropertyProjection Property<T>(Expression<Func<T, object>> expression) + { + return Projections.Property(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A projected property value + /// </summary> + public static PropertyProjection Property(Expression<Func<object>> expression) + { + return Projections.Property(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + public static IProjection SubQuery<T>(QueryOver<T> detachedQueryOver) + { + return Projections.SubQuery(detachedQueryOver.DetachedCriteria); + } + + /// <summary> + /// A property value sum + /// </summary> + public static AggregateProjection Sum<T>(Expression<Func<T, object>> expression) + { + return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body)); + } + + /// <summary> + /// A property value sum + /// </summary> + public static AggregateProjection Sum(Expression<Func<object>> expression) + { + return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body)); + } } } Added: trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2009-11-23 17:38:07 UTC (rev 4855) @@ -0,0 +1,23 @@ +using System; +using System.Linq.Expressions; + +using NHibernate.Impl; + +namespace NHibernate.Criterion +{ + public static class ProjectionsExtensions + { + /// <summary> + /// Create an alias for a projection + /// </summary> + /// <param name="projection">the projection instance</param> + /// <param name="alias">LambdaExpression returning an alias</param> + /// <returns>return NHibernate.Criterion.IProjection</returns> + public static IProjection WithAlias(this IProjection projection, + Expression<Func<object>> alias) + { + string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body); + return Projections.Alias(projection, aliasContainer); + } + } +} Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-22 15:34:59 UTC (rev 4854) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-23 17:38:07 UTC (rev 4855) @@ -515,6 +515,7 @@ <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" /> + <Compile Include="Criterion\ProjectionsExtensions.cs" /> <Compile Include="Dialect\MsSql2008Dialect.cs" /> <Compile Include="Dialect\InformixDialect0940.cs" /> <Compile Include="Dialect\InformixDialect1000.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855) @@ -0,0 +1,90 @@ +using System; +using System.Collections; + +using NUnit.Framework; + +using NHibernate.Criterion; + +namespace NHibernate.Test.Criteria.Lambda +{ + + [TestFixture] + public class ProjectionsFixture : LambdaFixtureBase + { + + private Child _subqueryChildAlias = null; + + private DetachedCriteria DetachedCriteriaAge + { + get + { + return ToDetachedCriteria(DetachedQueryOverAge); + } + } + + private QueryOver<Child> DetachedQueryOverAge + { + get + { + return + new QueryOver<Child>(() => _subqueryChildAlias) + .Where(() => _subqueryChildAlias.Nickname == "subquery name") + .Select(p => p.Age); + } + } + + [Test] + public void ArbitraryProjections() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .SetProjection(Projections.ProjectionList() + .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias")) + .Add(Projections.Avg("Age"), "personAgeProjectionAlias") + .Add(Projections.Avg("personAlias.Age")) + .Add(Projections.Count("Age")) + .Add(Projections.Count("personAlias.Age")) + .Add(Projections.CountDistinct("Age")) + .Add(Projections.CountDistinct("personAlias.Age")) + .Add(Projections.GroupProperty("Age")) + .Add(Projections.GroupProperty("personAlias.Age")) + .Add(Projections.Max("Age")) + .Add(Projections.Max("personAlias.Age")) + .Add(Projections.Min("Age")) + .Add(Projections.Min("personAlias.Age")) + .Add(Projections.Property("Age")) + .Add(Projections.Property("personAlias.Age")) + .Add(Projections.SubQuery(DetachedCriteriaAge)) + .Add(Projections.Sum("Age")) + .Add(Projections.Sum("personAlias.Age"))); + + Person personAlias = null; + Person personAgeProjectionAlias = null; + var actual = + CreateTestQueryOver<Person>(() => personAlias) + .Select(Projections.ProjectionList() + .Add(Projections.Avg<Person>(p => p.Age).WithAlias(() => personAgeProjectionAlias)) + .Add(Projections.Avg<Person>(p => p.Age), () => personAgeProjectionAlias) + .Add(Projections.Avg(() => personAlias.Age)) + .Add(Projections.Count<Person>(p => p.Age)) + .Add(Projections.Count(() => personAlias.Age)) + .Add(Projections.CountDistinct<Person>(p => p.Age)) + .Add(Projections.CountDistinct(() => personAlias.Age)) + .Add(Projections.GroupProperty<Person>(p => p.Age)) + .Add(Projections.GroupProperty(() => personAlias.Age)) + .Add(Projections.Max<Person>(p => p.Age)) + .Add(Projections.Max(() => personAlias.Age)) + .Add(Projections.Min<Person>(p => p.Age)) + .Add(Projections.Min(() => personAlias.Age)) + .Add(Projections.Property<Person>(p => p.Age)) + .Add(Projections.Property(() => personAlias.Age)) + .Add(Projections.SubQuery(DetachedQueryOverAge)) + .Add(Projections.Sum<Person>(p => p.Age)) + .Add(Projections.Sum(() => personAlias.Age))); + + AssertCriteriaAreEqual(expected, actual); + } + + } + +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-22 15:34:59 UTC (rev 4854) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-23 17:38:07 UTC (rev 4855) @@ -160,6 +160,7 @@ <Compile Include="Criteria\Enrolment.cs" /> <Compile Include="Criteria\Lambda\CriteriaAssertFixture.cs" /> <Compile Include="Criteria\Lambda\ExpressionProcessorFixture.cs" /> + <Compile Include="Criteria\Lambda\ProjectionsFixture.cs" /> <Compile Include="Criteria\Lambda\QueryOverFixture.cs" /> <Compile Include="Criteria\Lambda\IntegrationFixture.cs" /> <Compile Include="Criteria\Lambda\LambdaFixtureBase.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-22 15:35:07
|
Revision: 4854 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4854&view=rev Author: fabiomaulo Date: 2009-11-22 15:34:59 +0000 (Sun, 22 Nov 2009) Log Message: ----------- Release note for 2.1.2 Modified Paths: -------------- branches/2.1.x/nhibernate/releasenotes.txt Modified: branches/2.1.x/nhibernate/releasenotes.txt =================================================================== --- branches/2.1.x/nhibernate/releasenotes.txt 2009-11-22 15:17:52 UTC (rev 4853) +++ branches/2.1.x/nhibernate/releasenotes.txt 2009-11-22 15:34:59 UTC (rev 4854) @@ -1,3 +1,17 @@ +Build 2.1.2.GA (rev4853) +============================= + +** Bug + * [NH-2011] - Many-to-many inside a component will not be saved when using SaveOrUpdateCopy or Merge + +** Improvement + * [NH-2022] - Allow overriding in Query By Example + + +** Patch + * [NH-2007] - SesssionIdLoggingContext patch for big resultsets + * [NH-2019] - Clarification about the use of <import> for polymorphic queries + Build 2.1.1.GA (rev4814) ============================= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-22 15:18:04
|
Revision: 4853 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4853&view=rev Author: fabiomaulo Date: 2009-11-22 15:17:52 +0000 (Sun, 22 Nov 2009) Log Message: ----------- Merge r4852 (refactoring fix NH-2022) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Example.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Example.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Example.cs 2009-11-22 15:14:55 UTC (rev 4852) +++ trunk/nhibernate/src/NHibernate/Criterion/Example.cs 2009-11-22 15:17:52 UTC (rev 4853) @@ -57,9 +57,9 @@ } //private static readonly IPropertySelector NotNull = new NotNullPropertySelector(); - private static readonly IPropertySelector NotNullOrEmptyString = new NotNullOrEmptyStringPropertySelector(); - private static readonly IPropertySelector All = new AllPropertySelector(); - private static readonly IPropertySelector NotNullOrZero = new NotNullOrZeroPropertySelector(); + protected static readonly IPropertySelector NotNullOrEmptyString = new NotNullOrEmptyStringPropertySelector(); + protected static readonly IPropertySelector All = new AllPropertySelector(); + protected static readonly IPropertySelector NotNullOrZero = new NotNullOrZeroPropertySelector(); /// <summary> /// Implementation of <see cref="IPropertySelector"/> that includes all @@ -476,21 +476,22 @@ builder.Add(" and "); } - ICriterion crit; - if (propertyValue != null) - { - bool isString = propertyValue is String; - crit = (_isLikeEnabled && isString) ? - (ICriterion) new LikeExpression(propertyName, propertyValue.ToString(), _matchMode, escapeCharacter, _isIgnoreCaseEnabled) : - new SimpleExpression(propertyName, propertyValue, " = ", _isIgnoreCaseEnabled && isString); - } - else - { - crit = new NullExpression(propertyName); - } + ICriterion crit = propertyValue != null + ? GetNotNullPropertyCriterion(propertyValue, propertyName) + : new NullExpression(propertyName); builder.Add(crit.ToSqlString(criteria, cq, enabledFilters)); } + protected virtual ICriterion GetNotNullPropertyCriterion(object propertyValue, string propertyName) + { + bool isString = propertyValue is string; + return (_isLikeEnabled && isString) + ? (ICriterion) + new LikeExpression(propertyName, propertyValue.ToString(), _matchMode, escapeCharacter, + _isIgnoreCaseEnabled) + : new SimpleExpression(propertyName, propertyValue, " = ", _isIgnoreCaseEnabled && isString); + } + protected void AppendComponentCondition( String path, object component, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-22 15:15:20
|
Revision: 4852 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4852&view=rev Author: fabiomaulo Date: 2009-11-22 15:14:55 +0000 (Sun, 22 Nov 2009) Log Message: ----------- Refactoring (Fix NH-2022) Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Criterion/Example.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Criterion/Example.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Criterion/Example.cs 2009-11-22 06:28:42 UTC (rev 4851) +++ branches/2.1.x/nhibernate/src/NHibernate/Criterion/Example.cs 2009-11-22 15:14:55 UTC (rev 4852) @@ -57,9 +57,9 @@ } //private static readonly IPropertySelector NotNull = new NotNullPropertySelector(); - private static readonly IPropertySelector NotNullOrEmptyString = new NotNullOrEmptyStringPropertySelector(); - private static readonly IPropertySelector All = new AllPropertySelector(); - private static readonly IPropertySelector NotNullOrZero = new NotNullOrZeroPropertySelector(); + protected static readonly IPropertySelector NotNullOrEmptyString = new NotNullOrEmptyStringPropertySelector(); + protected static readonly IPropertySelector All = new AllPropertySelector(); + protected static readonly IPropertySelector NotNullOrZero = new NotNullOrZeroPropertySelector(); /// <summary> /// Implementation of <see cref="IPropertySelector"/> that includes all @@ -476,21 +476,22 @@ builder.Add(" and "); } - ICriterion crit; - if (propertyValue != null) - { - bool isString = propertyValue is String; - crit = (_isLikeEnabled && isString) ? - (ICriterion) new LikeExpression(propertyName, propertyValue.ToString(), _matchMode, escapeCharacter, _isIgnoreCaseEnabled) : - new SimpleExpression(propertyName, propertyValue, " = ", _isIgnoreCaseEnabled && isString); - } - else - { - crit = new NullExpression(propertyName); - } + ICriterion crit = propertyValue != null + ? GetNotNullPropertyCriterion(propertyValue, propertyName) + : new NullExpression(propertyName); builder.Add(crit.ToSqlString(criteria, cq, enabledFilters)); } + protected virtual ICriterion GetNotNullPropertyCriterion(object propertyValue, string propertyName) + { + bool isString = propertyValue is string; + return (_isLikeEnabled && isString) + ? (ICriterion) + new LikeExpression(propertyName, propertyValue.ToString(), _matchMode, escapeCharacter, + _isIgnoreCaseEnabled) + : new SimpleExpression(propertyName, propertyValue, " = ", _isIgnoreCaseEnabled && isString); + } + protected void AppendComponentCondition( String path, object component, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-22 06:28:52
|
Revision: 4851 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4851&view=rev Author: fabiomaulo Date: 2009-11-22 06:28:42 +0000 (Sun, 22 Nov 2009) Log Message: ----------- Preparing for release Modified Paths: -------------- branches/2.1.x/nhibernate/build-common/common.xml Modified: branches/2.1.x/nhibernate/build-common/common.xml =================================================================== --- branches/2.1.x/nhibernate/build-common/common.xml 2009-11-22 06:27:16 UTC (rev 4850) +++ branches/2.1.x/nhibernate/build-common/common.xml 2009-11-22 06:28:42 UTC (rev 4851) @@ -76,7 +76,7 @@ effectively SP0). --> - <property name="project.version" value="2.1.1.GA" overwrite="false" /> + <property name="project.version" value="2.1.2.GA" overwrite="false" /> <!-- Compute short project version (major.minor) using a regex --> <regex input="${project.version}" pattern="^(?'shortversion'\d+\.\d+)" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-22 06:27:24
|
Revision: 4850 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4850&view=rev Author: fabiomaulo Date: 2009-11-22 06:27:16 +0000 (Sun, 22 Nov 2009) Log Message: ----------- Minor Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs 2009-11-20 22:26:39 UTC (rev 4849) +++ branches/2.1.x/nhibernate/src/NHibernate/Cfg/XmlSchemas.cs 2009-11-22 06:27:16 UTC (rev 4850) @@ -10,12 +10,12 @@ private const string CfgSchemaResource = "NHibernate.nhibernate-configuration.xsd"; private const string MappingSchemaResource = "NHibernate.nhibernate-mapping.xsd"; - private readonly XmlSchema config = ReadXmlSchemaFromEmbeddedResource(CfgSchemaResource); - private readonly XmlSchema mapping = ReadXmlSchemaFromEmbeddedResource(MappingSchemaResource); + private static readonly XmlSchema ConfigSchema = ReadXmlSchemaFromEmbeddedResource(CfgSchemaResource); + private static readonly XmlSchema MappingSchema = ReadXmlSchemaFromEmbeddedResource(MappingSchemaResource); public XmlReaderSettings CreateConfigReaderSettings() { - XmlReaderSettings result = CreateXmlReaderSettings(config); + XmlReaderSettings result = CreateXmlReaderSettings(ConfigSchema); result.ValidationEventHandler += new ValidationEventHandler(ConfigSettingsValidationEventHandler); result.IgnoreComments = true; return result; @@ -23,7 +23,7 @@ public XmlReaderSettings CreateMappingReaderSettings() { - return CreateXmlReaderSettings(mapping); + return CreateXmlReaderSettings(MappingSchema); } private static XmlSchema ReadXmlSchemaFromEmbeddedResource(string resourceName) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2009-11-20 22:26:49
|
Revision: 4849 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4849&view=rev Author: ayenderahien Date: 2009-11-20 22:26:39 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Log creating a child session Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-11-20 21:28:47 UTC (rev 4848) +++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-11-20 22:26:39 UTC (rev 4849) @@ -2436,6 +2436,7 @@ if (rtn == null) { + log.DebugFormat("Creating child session with {0}", entityMode); rtn = new SessionImpl(this, entityMode); childSessionsByEntityMode.Add(entityMode, rtn); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-20 21:28:58
|
Revision: 4848 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4848&view=rev Author: ricbrown Date: 2009-11-20 21:28:47 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Added convenience syntax for negation of expressions. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-20 20:13:57 UTC (rev 4847) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-20 21:28:47 UTC (rev 4848) @@ -89,6 +89,16 @@ return Add(expression); } + public QueryOver<T> AndNot(Expression<Func<T, bool>> expression) + { + return AddNot(expression); + } + + public QueryOver<T> AndNot(Expression<Func<bool>> expression) + { + return AddNot(expression); + } + public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression) { return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); @@ -114,6 +124,16 @@ return Add(expression); } + public QueryOver<T> WhereNot(Expression<Func<T, bool>> expression) + { + return AddNot(expression); + } + + public QueryOver<T> WhereNot(Expression<Func<bool>> expression) + { + return AddNot(expression); + } + public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression) { return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); @@ -464,7 +484,19 @@ return this; } + private QueryOver<T> AddNot(Expression<Func<T, bool>> expression) + { + _criteria.Add(Restrictions.Not(ExpressionProcessor.ProcessExpression<T>(expression))); + return this; + } + private QueryOver<T> AddNot(Expression<Func<bool>> expression) + { + _criteria.Add(Restrictions.Not(ExpressionProcessor.ProcessExpression(expression))); + return this; + } + + ICriteria IQueryOver<T>.UnderlyingCriteria { get { return UnderlyingCriteria; } } @@ -477,6 +509,12 @@ IQueryOver<T> IQueryOver<T>.And(ICriterion expression) { return And(expression); } + IQueryOver<T> IQueryOver<T>.AndNot(Expression<Func<T, bool>> expression) + { return AndNot(expression); } + + IQueryOver<T> IQueryOver<T>.AndNot(Expression<Func<bool>> expression) + { return AndNot(expression); } + IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<T, object>> expression) { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } @@ -492,6 +530,12 @@ IQueryOver<T> IQueryOver<T>.Where(ICriterion expression) { return Where(expression); } + IQueryOver<T> IQueryOver<T>.WhereNot(Expression<Func<T, bool>> expression) + { return WhereNot(expression); } + + IQueryOver<T> IQueryOver<T>.WhereNot(Expression<Func<bool>> expression) + { return WhereNot(expression); } + IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<T, object>> expression) { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-20 20:13:57 UTC (rev 4847) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-20 21:28:47 UTC (rev 4848) @@ -50,6 +50,20 @@ IQueryOver<T> And(ICriterion expression); /// <summary> + /// Add negation of criterion expressed as a lambda expression + /// </summary> + /// <param name="expression">Lambda expression</param> + /// <returns>criteria instance</returns> + IQueryOver<T> AndNot(Expression<Func<T, bool>> expression); + + /// <summary> + /// Add negation of criterion expressed as a lambda expression + /// </summary> + /// <param name="expression">Lambda expression</param> + /// <returns>criteria instance</returns> + IQueryOver<T> AndNot(Expression<Func<bool>> expression); + + /// <summary> /// Add restriction to a property /// </summary> /// <param name="expression">Lambda expression containing path to property</param> @@ -64,14 +78,14 @@ IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression); /// <summary> - /// Identical semantics to Add() to allow more readable queries + /// Identical semantics to And() to allow more readable queries /// </summary> /// <param name="expression">Lambda expression</param> /// <returns>criteria instance</returns> IQueryOver<T> Where(Expression<Func<T, bool>> expression); /// <summary> - /// Identical semantics to Add() to allow more readable queries + /// Identical semantics to And() to allow more readable queries /// </summary> /// <param name="expression">Lambda expression</param> /// <returns>criteria instance</returns> @@ -83,6 +97,20 @@ IQueryOver<T> Where(ICriterion expression); /// <summary> + /// Identical semantics to AndNot() to allow more readable queries + /// </summary> + /// <param name="expression">Lambda expression</param> + /// <returns>criteria instance</returns> + IQueryOver<T> WhereNot(Expression<Func<T, bool>> expression); + + /// <summary> + /// Identical semantics to AndNot() to allow more readable queries + /// </summary> + /// <param name="expression">Lambda expression</param> + /// <returns>criteria instance</returns> + IQueryOver<T> WhereNot(Expression<Func<bool>> expression); + + /// <summary> /// Identical semantics to AndRestrictionOn() to allow more readable queries /// </summary> /// <param name="expression">Lambda expression</param> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-20 20:13:57 UTC (rev 4847) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-20 21:28:47 UTC (rev 4848) @@ -101,18 +101,39 @@ } [Test] + public void Negation() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .Add(Restrictions.Not(Restrictions.Eq("Name", "test name"))) + .Add(Restrictions.Not(Restrictions.Eq("personAlias.Name", "test name"))); + + Person personAlias = null; + IQueryOver<Person> actual = + CreateTestQueryOver<Person>(() => personAlias) + .AndNot(p => p.Name == "test name") + .AndNot(() => personAlias.Name == "test name"); + + AssertCriteriaAreEqual(expected, actual); + } + + [Test] public void Where_BehavesTheSameAs_And() { Person personAlias = null; QueryOver<Person> expected = (QueryOver<Person>) CreateTestQueryOver<Person>(() => personAlias) .And(() => personAlias.Name == "test name") - .And(p => p.Name == "test name"); + .And(p => p.Name == "test name") + .AndNot(() => personAlias.Name == "test name") + .AndNot(p => p.Name == "test name"); IQueryOver<Person> actual = CreateTestQueryOver<Person>(() => personAlias) .Where(() => personAlias.Name == "test name") - .Where(p => p.Name == "test name"); + .Where(p => p.Name == "test name") + .WhereNot(() => personAlias.Name == "test name") + .WhereNot(p => p.Name == "test name"); AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 20:14:05
|
Revision: 4847 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4847&view=rev Author: fabiomaulo Date: 2009-11-20 20:13:57 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Merge r4846 (fix NH-2011) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 20:00:56 UTC (rev 4846) +++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 20:13:57 UTC (rev 4847) @@ -1125,8 +1125,10 @@ ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); object[] targetComponentValues = componentType.GetPropertyValues(target[i], session); - ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, + object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); + if (!componentType.IsAnyType) + componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); copied[i] = target[i]; } else if (!types[i].IsAssociationType) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs 2009-11-20 20:13:57 UTC (rev 4847) @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2011 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void Test() + { + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Save(new Country {CountryCode = "SE"}); + tx.Commit(); + } + } + + var newOrder = new Order(); + newOrder.GroupComponent = new GroupComponent(); + newOrder.GroupComponent.Countries = new List<Country>(); + newOrder.GroupComponent.Countries.Add(new Country {CountryCode = "SE"}); + + Order mergedCopy; + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + mergedCopy = (Order) session.Merge(newOrder); + tx.Commit(); + } + } + + using (ISession session = OpenSession()) + { + var order = session.Get<Order>(mergedCopy.Id); + Assert.That(order.GroupComponent.Countries.Count, Is.EqualTo(1)); + } + + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete("from Order"); + session.Delete("from Country"); + tx.Commit(); + } + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml 2009-11-20 20:13:57 UTC (rev 4847) @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2011"> + + <class name="Order" table="Orders"> + + <id name="Id"> + <generator class="guid.comb"/> + </id> + + <component name="GroupComponent"> + + <bag name="Countries" table="OrderCountries" cascade="none"> + <key column="OrderId" /> + <many-to-many column="CountryCode" class="Country" /> + </bag> + + </component> + + </class> + + <class name="Country" table="Countries"> + + <id name="CountryCode" unsaved-value="null"> + <generator class="assigned"/> + </id> + + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs 2009-11-20 20:13:57 UTC (rev 4847) @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2011 +{ + public class Order + { + public virtual Guid Id { get; set; } + + public virtual GroupComponent GroupComponent { get; set; } + } + + public class GroupComponent + { + public virtual IList<Country> Countries { get; set; } + } + + public class Country + { + public virtual string CountryCode { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 20:00:56 UTC (rev 4846) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 20:13:57 UTC (rev 4847) @@ -665,6 +665,8 @@ <Compile Include="NHSpecificTest\NH2000\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2003\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2003\Model.cs" /> + <Compile Include="NHSpecificTest\NH2011\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2011\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> <Compile Include="NHSpecificTest\NH473\Fixture.cs" /> <Compile Include="NHSpecificTest\NH473\Parent.cs" /> @@ -2078,6 +2080,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2011\Mappings.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\Animal.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\AnotherEntity.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\Role.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 20:01:05
|
Revision: 4846 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4846&view=rev Author: fabiomaulo Date: 2009-11-20 20:00:56 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Fix NH-2011 Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Type/TypeFactory.cs branches/2.1.x/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/ branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 16:07:42 UTC (rev 4845) +++ branches/2.1.x/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 20:00:56 UTC (rev 4846) @@ -1125,8 +1125,10 @@ ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); object[] targetComponentValues = componentType.GetPropertyValues(target[i], session); - ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, + object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); + if (!componentType.IsAnyType) + componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); copied[i] = target[i]; } else if (!types[i].IsAssociationType) Added: branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs (rev 0) +++ branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs 2009-11-20 20:00:56 UTC (rev 4846) @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2011 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void Test() + { + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Save(new Country {CountryCode = "SE"}); + tx.Commit(); + } + } + + var newOrder = new Order(); + newOrder.GroupComponent = new GroupComponent(); + newOrder.GroupComponent.Countries = new List<Country>(); + newOrder.GroupComponent.Countries.Add(new Country {CountryCode = "SE"}); + + Order mergedCopy; + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + mergedCopy = (Order) session.Merge(newOrder); + tx.Commit(); + } + } + + using (ISession session = OpenSession()) + { + var order = session.Get<Order>(mergedCopy.Id); + Assert.That(order.GroupComponent.Countries.Count, Is.EqualTo(1)); + } + + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete("from Order"); + session.Delete("from Country"); + tx.Commit(); + } + } + } + } +} \ No newline at end of file Added: branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml (rev 0) +++ branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml 2009-11-20 20:00:56 UTC (rev 4846) @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2011"> + + <class name="Order" table="Orders"> + + <id name="Id"> + <generator class="guid.comb"/> + </id> + + <component name="GroupComponent"> + + <bag name="Countries" table="OrderCountries" cascade="none"> + <key column="OrderId" /> + <many-to-many column="CountryCode" class="Country" /> + </bag> + + </component> + + </class> + + <class name="Country" table="Countries"> + + <id name="CountryCode" unsaved-value="null"> + <generator class="assigned"/> + </id> + + </class> + +</hibernate-mapping> Added: branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs (rev 0) +++ branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs 2009-11-20 20:00:56 UTC (rev 4846) @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2011 +{ + public class Order + { + public virtual Guid Id { get; set; } + + public virtual GroupComponent GroupComponent { get; set; } + } + + public class GroupComponent + { + public virtual IList<Country> Countries { get; set; } + } + + public class Country + { + public virtual string CountryCode { get; set; } + } +} Modified: branches/2.1.x/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 16:07:42 UTC (rev 4845) +++ branches/2.1.x/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 20:00:56 UTC (rev 4846) @@ -606,6 +606,8 @@ <Compile Include="NHSpecificTest\NH2000\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2003\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2003\Model.cs" /> + <Compile Include="NHSpecificTest\NH2011\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2011\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> <Compile Include="NHSpecificTest\NH473\Fixture.cs" /> <Compile Include="NHSpecificTest\NH473\Parent.cs" /> @@ -2019,6 +2021,7 @@ <EmbeddedResource Include="DriverTest\MultiTypeEntity.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2011\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\ManyToOneFilters20Behaviour\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2000\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2003\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 16:07:52
|
Revision: 4845 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4845&view=rev Author: fabiomaulo Date: 2009-11-20 16:07:42 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Merge (fix NH-2019) Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/query_hql.xml Modified: trunk/nhibernate/doc/reference/modules/query_hql.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/query_hql.xml 2009-11-20 16:06:46 UTC (rev 4844) +++ trunk/nhibernate/doc/reference/modules/query_hql.xml 2009-11-20 16:07:42 UTC (rev 4845) @@ -294,7 +294,9 @@ Note that these last two queries will require more than one SQL <literal>SELECT</literal>. This means that the <literal>order by</literal> clause does not correctly order the whole result set. </para> - + <para> + In order to use non-mapped base classes or interfaces in HQL queries, they have to be imported. See <xref linkend="mapping-declaration-import"/> for more information. + </para> </sect1> <sect1 id="queryhql-where"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 16:06:53
|
Revision: 4844 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4844&view=rev Author: fabiomaulo Date: 2009-11-20 16:06:46 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Fix NH-2019 Modified Paths: -------------- branches/2.1.x/nhibernate/doc/reference/modules/query_hql.xml Modified: branches/2.1.x/nhibernate/doc/reference/modules/query_hql.xml =================================================================== --- branches/2.1.x/nhibernate/doc/reference/modules/query_hql.xml 2009-11-20 15:57:26 UTC (rev 4843) +++ branches/2.1.x/nhibernate/doc/reference/modules/query_hql.xml 2009-11-20 16:06:46 UTC (rev 4844) @@ -294,7 +294,9 @@ Note that these last two queries will require more than one SQL <literal>SELECT</literal>. This means that the <literal>order by</literal> clause does not correctly order the whole result set. </para> - + <para> + In order to use non-mapped base classes or interfaces in HQL queries, they have to be imported. See <xref linkend="mapping-declaration-import"/> for more information. + </para> </sect1> <sect1 id="queryhql-where"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 15:57:34
|
Revision: 4843 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4843&view=rev Author: fabiomaulo Date: 2009-11-20 15:57:26 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Merge the fix of NH-2007 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs Modified: trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-20 15:55:07 UTC (rev 4842) +++ trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-20 15:57:26 UTC (rev 4843) @@ -1,16 +1,12 @@ using System; -using log4net; namespace NHibernate.Impl { - using System.Web; - public class SessionIdLoggingContext : IDisposable { - [ThreadStatic] private static Guid? CurrentSessionId; + [ThreadStatic] + private static Guid? CurrentSessionId; - private const string CurrentSessionIdKey = "NHibernate.Impl.SessionIdLoggingContext.CurrentSessionId"; - private readonly Guid? oldSessonId; public SessionIdLoggingContext(Guid id) @@ -20,30 +16,25 @@ } /// <summary> - /// Error handling in this case will only kick in if we cannot set values on the TLS - /// this is usally the case if we are called from the finalizer, since this is something - /// that we do only for logging, we ignore the error. + /// We always set the result to use a thread static variable, on the face of it, + /// it looks like it is not a valid choice, since ASP.Net and WCF may decide to switch + /// threads on us. But, since SessionIdLoggingContext is only used inside NH calls, and since + /// NH calls are never async, this isn't an issue for us. + /// In addition to that, attempting to match to the current context has proven to be performance hit. /// </summary> public static Guid? SessionId { - get - { - if (HttpContext.Current != null) - return (Guid?)HttpContext.Current.Items[CurrentSessionIdKey]; - return CurrentSessionId; - } - set - { - if (HttpContext.Current != null) - HttpContext.Current.Items[CurrentSessionIdKey] = value; - else - CurrentSessionId = value; - } + get { return CurrentSessionId; } + set { CurrentSessionId = value; } } + #region IDisposable Members + public void Dispose() { SessionId = oldSessonId; } + + #endregion } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2009-11-20 15:55:22
|
Revision: 4842 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4842&view=rev Author: fabiomaulo Date: 2009-11-20 15:55:07 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Minor (cleaned) Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-20 15:19:50 UTC (rev 4841) +++ branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-20 15:55:07 UTC (rev 4842) @@ -1,13 +1,11 @@ using System; -using log4net; namespace NHibernate.Impl { - using System.Web; - public class SessionIdLoggingContext : IDisposable { - [ThreadStatic] private static Guid? CurrentSessionId; + [ThreadStatic] + private static Guid? CurrentSessionId; private readonly Guid? oldSessonId; @@ -20,25 +18,23 @@ /// <summary> /// We always set the result to use a thread static variable, on the face of it, /// it looks like it is not a valid choice, since ASP.Net and WCF may decide to switch - /// threads on us. But, since SessionIdLoggingContext is only used inside NH calls, and since - /// NH calls are never async, this isn't an issue for us. - /// In addition to that, attempting to match to the current context has proven to be performance hit. + /// threads on us. But, since SessionIdLoggingContext is only used inside NH calls, and since + /// NH calls are never async, this isn't an issue for us. + /// In addition to that, attempting to match to the current context has proven to be performance hit. /// </summary> public static Guid? SessionId { - get - { - return CurrentSessionId; - } - set - { - CurrentSessionId = value; - } + get { return CurrentSessionId; } + set { CurrentSessionId = value; } } + #region IDisposable Members + public void Dispose() { SessionId = oldSessonId; } + + #endregion } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2009-11-20 15:19:57
|
Revision: 4841 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4841&view=rev Author: ayenderahien Date: 2009-11-20 15:19:50 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Log when creating child session Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionImpl.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionImpl.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-11-20 15:18:26 UTC (rev 4840) +++ branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-11-20 15:19:50 UTC (rev 4841) @@ -2371,6 +2371,7 @@ if (rtn == null) { + log.DebugFormat("Creating child session with {0}", entityMode); rtn = new SessionImpl(this, entityMode); childSessionsByEntityMode.Add(entityMode, rtn); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2009-11-20 15:18:40
|
Revision: 4840 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4840&view=rev Author: ayenderahien Date: 2009-11-20 15:18:26 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Fixing perf problem with SessionIdLoggingContext (NH-2007) Modified Paths: -------------- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs Modified: branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs =================================================================== --- branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-19 16:04:43 UTC (rev 4839) +++ branches/2.1.x/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-11-20 15:18:26 UTC (rev 4840) @@ -9,8 +9,6 @@ { [ThreadStatic] private static Guid? CurrentSessionId; - private const string CurrentSessionIdKey = "NHibernate.Impl.SessionIdLoggingContext.CurrentSessionId"; - private readonly Guid? oldSessonId; public SessionIdLoggingContext(Guid id) @@ -20,24 +18,21 @@ } /// <summary> - /// Error handling in this case will only kick in if we cannot set values on the TLS - /// this is usally the case if we are called from the finalizer, since this is something - /// that we do only for logging, we ignore the error. + /// We always set the result to use a thread static variable, on the face of it, + /// it looks like it is not a valid choice, since ASP.Net and WCF may decide to switch + /// threads on us. But, since SessionIdLoggingContext is only used inside NH calls, and since + /// NH calls are never async, this isn't an issue for us. + /// In addition to that, attempting to match to the current context has proven to be performance hit. /// </summary> public static Guid? SessionId { get { - if (HttpContext.Current != null) - return (Guid?)HttpContext.Current.Items[CurrentSessionIdKey]; return CurrentSessionId; } set { - if (HttpContext.Current != null) - HttpContext.Current.Items[CurrentSessionIdKey] = value; - else - CurrentSessionId = value; + CurrentSessionId = value; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |