|
From: <ric...@us...> - 2011-05-25 21:16:08
|
Revision: 5871
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5871&view=rev
Author: ricbrown
Date: 2011-05-25 21:16:01 +0000 (Wed, 25 May 2011)
Log Message:
-----------
NH-2733 (NH-2683): Using an expression in QueryOver gives: Lambda Parameter not in scope
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs
Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-25 12:47:06 UTC (rev 5870)
+++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-25 21:16:01 UTC (rev 5871)
@@ -334,10 +334,14 @@
if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
{
+ if (IsMemberExpression(memberExpression.Expression))
+ return true;
+
// if the member has a null value, it was an alias
- if (EvaluatesToNull(memberExpression.Expression))
- return true;
+ return EvaluatesToNull(memberExpression.Expression);
}
+
+ return IsMemberExpression(memberExpression.Expression);
}
if (expression is UnaryExpression)
@@ -358,9 +362,16 @@
if (_customProjectionProcessors.ContainsKey(signature))
return true;
+ if (methodCallExpression.Method.Name == "First")
+ {
+ if (IsMemberExpression(methodCallExpression.Arguments[0]))
+ return true;
+
+ return EvaluatesToNull(methodCallExpression.Arguments[0]);
+ }
+
if (methodCallExpression.Method.Name == "GetType"
- || methodCallExpression.Method.Name == "get_Item"
- || methodCallExpression.Method.Name == "First")
+ || methodCallExpression.Method.Name == "get_Item")
{
if (IsMemberExpression(methodCallExpression.Object))
return true;
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-25 12:47:06 UTC (rev 5870)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-25 21:16:01 UTC (rev 5871)
@@ -1,5 +1,6 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -19,35 +20,165 @@
public void TestFindMemberExpressionReference()
{
Expression<Func<Person, string>> e = (Person p) => p.Name;
- string property = ExpressionProcessor.FindMemberExpression(e.Body);
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
Assert.AreEqual("Name", property);
}
[Test]
+ public void TestFindMemberExpressionReferenceAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<string>> e = () => personAlias.Name;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.Name", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionComponent()
+ {
+ Expression<Func<Person, string>> e = (Person p) => p.Father.Name;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("Father.Name", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionComponentAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<string>> e = () => personAlias.Father.Name;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.Father.Name", property);
+ }
+
+ [Test]
public void TestFindMemberExpressionValue()
{
Expression<Func<Person, object>> e = (Person p) => p.Age;
- string property = ExpressionProcessor.FindMemberExpression(e.Body);
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
Assert.AreEqual("Age", property);
}
[Test]
+ public void TestFindMemberExpressionValueAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.Age;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.Age", property);
+ }
+
+ [Test]
public void TestFindMemberExpressionSubCollectionIndex()
{
Expression<Func<Person, object>> e = (Person p) => p.PersonList[0].Children;
- string property = ExpressionProcessor.FindMemberExpression(e.Body);
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
Assert.AreEqual("PersonList.Children", property);
}
[Test]
+ public void TestFindMemberExpressionSubCollectionIndexAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.PersonList[0].Children;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.PersonList.Children", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionSubCollectionFirst()
+ {
+ Expression<Func<Person, object>> e = (Person p) => p.PersonList.First().Children;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("PersonList.Children", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionSubCollectionFirstAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.PersonList.First().Children;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.PersonList.Children", property);
+ }
+
+ [Test]
public void TestFindMemberExpressionSubCollectionExtensionMethod()
{
Expression<Func<Person, object>> e = (Person p) => p.PersonList.First().Children;
- string property = ExpressionProcessor.FindMemberExpression(e.Body);
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
Assert.AreEqual("PersonList.Children", property);
}
[Test]
+ public void TestFindMemberExpressionSubCollectionExtensionMethodAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.PersonList.First().Children;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.PersonList.Children", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionClass()
+ {
+ Expression<Func<Person, object>> e = (Person p) => p.GetType();
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("class", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionClassAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.GetType();
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.class", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionNullableValue()
+ {
+ Expression<Func<Person, object>> e = (Person p) => p.NullableGender.Value;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("NullableGender", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionNullableValueAlias()
+ {
+ Person personAlias = null;
+ Expression<Func<object>> e = () => personAlias.NullableGender.Value;
+ string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString();
+ Assert.AreEqual("personAlias.NullableGender", property);
+ }
+
+ [Test]
+ public void TestFindMemberExpressionConstants()
+ {
+ var children = new List<Child> { new Child { Nickname = "test nickname" } };
+ Person person =
+ new Person()
+ {
+ Name = "test name",
+ NullableAge = 4,
+ Children = children,
+ };
+
+ Assert.That(Projection(() => person.Name), Is.EqualTo("test name"));
+ Assert.That(Projection(() => "test name"), Is.EqualTo("test name"));
+ Assert.That(Projection(() => person.NullableAge.Value), Is.EqualTo(4));
+ Assert.That(Projection(() => person.GetType()), Is.EqualTo(typeof(Person)));
+ Assert.That(Projection(() => person.Children.First().Nickname), Is.EqualTo("test nickname"));
+ Assert.That(Projection(() => children[0].Nickname), Is.EqualTo("test nickname"));
+ }
+
+ private T Projection<T>(Expression<Func<T>> e)
+ {
+ var constantProjection = ExpressionProcessor.FindMemberProjection(e.Body);
+ return (T)typeof(ConstantProjection).GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(constantProjection);
+ }
+
+ [Test]
public void TestEvaluatePropertyExpression()
{
string testName = "testName";
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733
___________________________________________________________________
Added: bugtraq:url
+ http://jira.nhibernate.org/browse/%BUGID%
Added: bugtraq:logregex
+ NH-\d+
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs 2011-05-25 21:16:01 UTC (rev 5871)
@@ -0,0 +1,81 @@
+using System;
+using System.Linq.Expressions;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH2733
+{
+ public interface ISpecification
+ {
+ Expression Expression { get; }
+ }
+
+ public interface ISpecification<T> : ISpecification
+ {
+ Expression<Func<T, bool>> Predicate { get; }
+ }
+
+ public class Specification<T>
+ {
+ public Expression<Func<T, bool>> Predicate { get; protected set; }
+
+ public Expression Expression
+ {
+ get
+ {
+ return Predicate;
+ }
+ }
+
+ public Specification(Expression<Func<T, bool>> predicate)
+ {
+ Predicate = predicate;
+ }
+ }
+
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ Item Item = null;
+
+ protected override void OnSetUp()
+ {
+ using (ISession session = Sfi.OpenSession())
+ {
+ var item = new Item();
+ session.Persist(item);
+ session.Flush();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (ISession session = Sfi.OpenSession())
+ {
+ session.CreateQuery("delete from Item").ExecuteUpdate();
+ session.Flush();
+ }
+ base.OnTearDown();
+ }
+
+ public static Expression<Func<Item, bool>> GetExpression(DateTime startTime)
+ {
+ return item => item.Details.StartTime == startTime;
+ }
+
+ [Test]
+ public void CanUseExpressionForWhere()
+ {
+ using (ISession session = Sfi.OpenSession())
+ {
+ IQueryOver<Item, Item> query = session.QueryOver(() => Item);
+
+ var start = DateTime.UtcNow;
+
+ query
+ .Where(GetExpression(start));
+
+ query.List();
+ }
+ }
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml 2011-05-25 21:16:01 UTC (rev 5871)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.NHSpecificTest.NH2733"
+ assembly="NHibernate.Test">
+
+ <class name="Item" table="`Item_Table`">
+ <id name="Id">
+ <generator class="native"/>
+ </id>
+ <component name="Details">
+ <property name="StartTime" />
+ </component>
+ </class>
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs 2011-05-25 21:16:01 UTC (rev 5871)
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+
+namespace NHibernate.Test.NHSpecificTest.NH2733
+{
+ public class Item
+ {
+ public virtual int Id { get; set; }
+
+ public class ItemDetails
+ {
+ public virtual DateTime? StartTime { get; set; }
+ }
+
+ public virtual ItemDetails Details { get; set; }
+
+ public Item()
+ {
+ Details = new ItemDetails();
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 12:47:06 UTC (rev 5870)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 21:16:01 UTC (rev 5871)
@@ -854,6 +854,8 @@
<Compile Include="NHSpecificTest\NH2705\SubItemBase.cs" />
<Compile Include="NHSpecificTest\NH2705\SubItemDetails.cs" />
<Compile Include="NHSpecificTest\NH2705\Test.cs" />
+ <Compile Include="NHSpecificTest\NH2733\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH2733\Model.cs" />
<Compile Include="NHSpecificTest\Properties\CompositePropertyRefTest.cs" />
<Compile Include="NHSpecificTest\Properties\DynamicEntityTest.cs" />
<Compile Include="NHSpecificTest\Properties\Model.cs" />
@@ -2696,6 +2698,7 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="NHSpecificTest\NH2733\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2317\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2366\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2404\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|