Skip to content

Commit

Permalink
Added test case LinqExpressionOnParameterEvaluated for issue original…
Browse files Browse the repository at this point in the history
…ly described under nhibernate#2244
  • Loading branch information
Vasily Kabanov committed Nov 26, 2019
1 parent d8931ac commit 133b26d
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 2 deletions.
94 changes: 94 additions & 0 deletions src/NHibernate.DomainModel/ProductMaterial.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

using System;
using System.Collections.Generic;

namespace NHibernate.DomainModel
{
public class EntityVersioned<TKey>
where TKey: struct, IComparable<TKey>
{
public static IEqualityComparer<TKey> KeyComparer { get; protected internal set; } = EqualityComparer<TKey>.Default;

public virtual TKey Id { get; set; }

public virtual int IntegrityVersion { get; set; }

/// <summary>
/// No business key, any 2 instances with same Ids considered equal
/// </summary>
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
return true;

if (!(obj is EntityVersioned<TKey> thatEntity))
return false;

var thisType = GetTypeUnproxied();
var thatType = thatEntity.GetTypeUnproxied();

if (thisType != thatType)
return false;

return KeyComparer.Equals(Id, thatEntity.Id);
}

public override int GetHashCode()
{
return Id.GetHashCode();
}

public virtual bool IsTransient => IntegrityVersion <= 0;

protected virtual System.Type GetTypeUnproxied()
{
return GetTypeUnproxied(this);
}

protected virtual bool IsPersistentWithSameIdAs(EntityVersioned<TKey> compareTo)
{
if (compareTo == null) throw new ArgumentNullException(nameof(compareTo));

return !IsTransient && !compareTo.IsTransient && KeyComparer.Equals(Id, compareTo.Id);
}

public static System.Type GetTypeUnproxied(EntityVersioned<TKey> obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));

var result = obj.GetType();

while (IsProxyOrAccessor(result))
result = result.BaseType;

return result;
}

public static bool IsProxyOrAccessor(System.Type type) => type.Assembly.IsDynamic
|| typeof(Intercept.IFieldInterceptorAccessor).IsAssignableFrom(type)
|| typeof(Proxy.INHibernateProxy).IsAssignableFrom(type);
}

public class EntityVersionedWithName<TKey> : EntityVersioned<TKey>
where TKey: struct, IComparable<TKey>
{
public virtual string Name { get; set; }
}

public class Material : EntityVersionedWithName<int>
{

public virtual MaterialDefinition MaterialDefinition { get; set; }

public virtual ProductDefinition ProductDefinition { get; set; }
}

public class MaterialDefinition : EntityVersionedWithName<int>
{
}

public class ProductDefinition : EntityVersionedWithName<int>
{
public virtual MaterialDefinition MaterialDefinition { get; set; }
}
}
35 changes: 35 additions & 0 deletions src/NHibernate.DomainModel/ProductMaterial.hbm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.DomainModel" assembly="NHibernate.DomainModel" default-lazy="false">

<class name="Material" >
<id name="Id" type="Int32">
<generator class="assigned"/>
</id>
<version name="IntegrityVersion" column="IntegrityVersion" unsaved-value="0" />

<many-to-one name="MaterialDefinition" class="MaterialDefinition" column="MaterialDefinitionId" not-null="true" not-found="exception" />
<many-to-one name="ProductDefinition" class="ProductDefinition" column="ProductDefinitionId" not-null="true" not-found="exception" />

<property name="Name" type="string" />
</class>

<class name="MaterialDefinition">
<id name="Id" type="Int32">
<generator class="assigned"/>
</id>
<version name="IntegrityVersion" column="IntegrityVersion" unsaved-value="0" />

<property name="Name" type="string" />
</class>

<class name="ProductDefinition">
<id name="Id" type="Int32">
<generator class="assigned"/>
</id>
<version name="IntegrityVersion" column="IntegrityVersion" unsaved-value="0" />
<many-to-one name="MaterialDefinition" class="MaterialDefinition" column="MaterialDefinitionId" not-null="true" not-found="exception" cascade="save-update" />

<property name="Name" type="string" />
</class>

</hibernate-mapping>
76 changes: 76 additions & 0 deletions src/NHibernate.Test/Linq/LinqQueriesReadWrite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Linq;
using NHibernate.DomainModel;
using NUnit.Framework;

namespace NHibernate.Test.Linq
{
/// <summary>
/// Self-contained setup
/// </summary>
[TestFixture]
public class LinqQueriesReadWrite : TestCase
{
private static readonly ProductDefinition productDefinition1 = new ProductDefinition() { Id = 1000, MaterialDefinition = new MaterialDefinition { Id = 1 } };
private static readonly ProductDefinition productDefinition2 = new ProductDefinition() { Id = 1001, MaterialDefinition = new MaterialDefinition { Id = 2 } };
private static readonly Material material1 = new Material {Id = 1, MaterialDefinition = productDefinition1.MaterialDefinition, ProductDefinition = productDefinition1};
private static readonly Material material2 = new Material {Id = 2, MaterialDefinition = productDefinition2.MaterialDefinition, ProductDefinition = productDefinition2};

protected override string[] Mappings
{
get { return new[] {"ProductMaterial.hbm.xml"}; }
}

protected override void OnSetUp()
{
using (var session = OpenSession(true))
{
session.Save(productDefinition1);
session.Save(productDefinition2);
session.Save(material1);
session.Save(material2);

session.Transaction.Commit();
}
base.OnSetUp();
}

protected override void OnTearDown()
{
using (var session = OpenSession(true))
{
session.Delete(productDefinition1);
session.Delete(productDefinition2);
session.Delete(material1);
session.Delete(material2);

session.Transaction.Commit();
}

base.OnTearDown();
}

[Test(Description = "#2244")]
public void LinqExpressionOnParameterEvaluated()
{
using (var session = OpenSession())
{
var selectedProducts = new[] { productDefinition1 };

var query = session.Query<Material>()
.Where(x => selectedProducts.Contains(x.ProductDefinition) && selectedProducts.Select(y => y.MaterialDefinition).Contains(x.MaterialDefinition));

//var sessionImpl = session.GetSessionImplementation();
//var factoryImplementor = sessionImpl.Factory;

//var nhLinqExpression = new NhLinqExpression(query.Expression, factoryImplementor);
//var translatorFactory = new ASTQueryTranslatorFactory();
//var translator = translatorFactory.CreateQueryTranslators(nhLinqExpression, null, false, sessionImpl.EnabledFilters, factoryImplementor).First();

var result = query.ToList();

Assert.AreEqual(1, result.Count);
Assert.AreEqual(material1, result.Single());
}
}
}
}
5 changes: 3 additions & 2 deletions src/NHibernate.Test/Linq/LinqTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ protected override string[] Mappings
"Northwind.Mappings.User.hbm.xml",
"Northwind.Mappings.TimeSheet.hbm.xml",
"Northwind.Mappings.Animal.hbm.xml",
"Northwind.Mappings.Patient.hbm.xml"
"Northwind.Mappings.Patient.hbm.xml",
"ProductMaterial.hbm.xml"
};
}
}
Expand Down Expand Up @@ -69,4 +70,4 @@ protected override void OnTearDown()
Assert.That(entities.Select(x => entityIdGetter(x)), Is.EquivalentTo(expectedIds));
}
}
}
}
8 changes: 8 additions & 0 deletions src/NHibernate.Test/TestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,14 @@ protected virtual ISession OpenSession()
return Sfi.OpenSession();
}

protected virtual ISession OpenSession(bool beginTransaction)
{
var result = Sfi.OpenSession();
if (beginTransaction)
result.BeginTransaction();
return result;
}

protected virtual ISession OpenSession(IInterceptor sessionLocalInterceptor)
{
return Sfi.WithOptions().Interceptor(sessionLocalInterceptor).OpenSession();
Expand Down

0 comments on commit 133b26d

Please sign in to comment.