Skip to content
Open
3 changes: 2 additions & 1 deletion src/NHibernate.DomainModel/Northwind/Entities/Animal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public class Animal
public virtual Animal Father { get; set; }
public virtual IList<Animal> Children { get; set; }
public virtual string SerialNumber { get; set; }

public virtual string FatherSerialNumber => Father?.SerialNumber;
public virtual bool HasFather => Father != null;
public virtual Animal FatherOrMother => Father ?? Mother;
}

Expand Down
18 changes: 18 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Entities/DynamicUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections;

namespace NHibernate.DomainModel.Northwind.Entities
{
public class DynamicUser : IEnumerable
{
public virtual int Id { get; set; }

public virtual dynamic Properties { get; set; }

public virtual IDictionary Settings { get; set; }

public virtual IEnumerator GetEnumerator()
{
throw new System.NotImplementedException();
}
}
}
5 changes: 5 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Entities/Northwind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public IQueryable<User> Users
get { return _session.Query<User>(); }
}

public IQueryable<DynamicUser> DynamicUsers
{
get { return _session.Query<DynamicUser>(); }
}

public IQueryable<PatientRecord> PatientRecords
{
get { return _session.Query<PatientRecord>(); }
Expand Down
1 change: 1 addition & 0 deletions src/NHibernate.DomainModel/Northwind/Entities/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public class Role
public virtual bool IsActive { get; set; }
public virtual AnotherEntity Entity { get; set; }
public virtual Role ParentRole { get; set; }
public virtual User CreatedBy { get; set; } // Not mapped
}
}
6 changes: 6 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Entities/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,16 @@ public class User : IUser, IEntity

public virtual FeatureSet Features { get; set; }

public virtual User NotMappedUser => this;

public virtual EnumStoredAsString Enum1 { get; set; }

public virtual EnumStoredAsString? NullableEnum1 { get; set; }

public virtual EnumStoredAsInt32 Enum2 { get; set; }

public virtual EnumStoredAsInt32? NullableEnum2 { get; set; }

public virtual IUser CreatedBy { get; set; }

public virtual IUser ModifiedBy { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ public class UserComponent
public string Property1 { get; set; }
public string Property2 { get; set; }
public UserComponent2 OtherComponent { get; set; }

public string Property3 => $"{Property1}{Property2}";
}

public class UserComponent2
{
public string OtherProperty1 { get; set; }

public string OtherProperty2 => OtherProperty1;
}
}
}
3 changes: 3 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Entities/UserDto.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace NHibernate.DomainModel.Northwind.Entities
{
Expand All @@ -9,11 +10,13 @@ public class UserDto
public virtual int InvalidLoginAttempts { get; set; }
public virtual string RoleName { get; set; }
public virtual UserDto2 Dto2 { get; set; }
public virtual List<UserDto2> Dto2List { get; set; } = new List<UserDto2>();

public UserDto(int id, string name)
{
Id = id;
Name = name;
Dto2 = new UserDto2();
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Mappings/DynamicUser.hbm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.DomainModel.Northwind.Entities" assembly="NHibernate.DomainModel">
<class name="DynamicUser" mutable="false">
<subselect>
select * from Users
</subselect>

<id name="Id" column="UserId" type="Int32">
<generator class="assigned" />
</id>

<dynamic-component name="Properties">
<property name="Name" type="AnsiString" />
<property name="Enum1" type="NHibernate.DomainModel.Northwind.Entities.EnumStoredAsStringType, NHibernate.DomainModel">
<column name="Enum1" length="12" />
</property>
<many-to-one name="CreatedBy" class="User" not-null="true" lazy="false">
<column name="CreatedById" not-null="true" />
</many-to-one>
</dynamic-component>

<dynamic-component name="Settings">
<property name="Property1" type="AnsiString" />
<property name="Property2" type="AnsiString" />
<many-to-one name="ModifiedBy" class="User" lazy="false">
<column name="ModifiedById" />
</many-to-one>
</dynamic-component>
</class>
</hibernate-mapping>
6 changes: 6 additions & 0 deletions src/NHibernate.DomainModel/Northwind/Mappings/User.hbm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@
<column name="Enum1" length="12" />
</property>

<property name="NullableEnum1" type="NHibernate.DomainModel.Northwind.Entities.EnumStoredAsStringType, NHibernate.DomainModel"
formula="(case when Enum1 = 'Unspecified' then null else Enum1 end)" insert="false" update="false">
</property>

<property name="Enum2" not-null="true" />

<property name="NullableEnum2" formula="(case when Enum2 = 0 then null else Enum2 end)" insert="false" update="false" />

<property name="Features" not-null="true" />

<many-to-one name="Role" class="Role">
Expand Down
37 changes: 37 additions & 0 deletions src/NHibernate.Test/Async/Linq/EnumTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,42 @@ public async Task CanQueryOnEnumStoredAsString_Small_1Async()

Assert.AreEqual(expectedCount, query.Count);
}

[Test]
public async Task ConditionalNavigationPropertyAsync()
{
EnumStoredAsString? type = null;
await (db.Users.Where(o => o.Enum1 == EnumStoredAsString.Large).ToListAsync());
await (db.Users.Where(o => EnumStoredAsString.Large != o.Enum1).ToListAsync());
await (db.Users.Where(o => (o.NullableEnum1 ?? EnumStoredAsString.Large) == EnumStoredAsString.Medium).ToListAsync());
await (db.Users.Where(o => ((o.NullableEnum1 ?? type) ?? o.Enum1) == EnumStoredAsString.Medium).ToListAsync());

await (db.Users.Where(o => (o.NullableEnum1.HasValue ? o.Enum1 : EnumStoredAsString.Unspecified) == EnumStoredAsString.Medium).ToListAsync());
await (db.Users.Where(o => (o.Enum1 != EnumStoredAsString.Large
? (o.NullableEnum1.HasValue ? o.Enum1 : EnumStoredAsString.Unspecified)
: EnumStoredAsString.Small) == EnumStoredAsString.Medium).ToListAsync());

await (db.Users.Where(o => (o.Enum1 == EnumStoredAsString.Large ? o.Role : o.Role).Name == "test").ToListAsync());
}

[Test]
public async Task CanQueryComplexExpressionOnEnumStoredAsStringAsync()
{
var type = EnumStoredAsString.Unspecified;
var query = await ((from user in db.Users
where (user.NullableEnum1 == EnumStoredAsString.Large
? EnumStoredAsString.Medium
: user.NullableEnum1 ?? user.Enum1
) == type
select new
{
user,
simple = user.Enum1,
condition = user.Enum1 == EnumStoredAsString.Large ? EnumStoredAsString.Medium : user.Enum1,
coalesce = user.NullableEnum1 ?? EnumStoredAsString.Medium
}).ToListAsync());

Assert.That(query.Count, Is.EqualTo(0));
}
}
}
28 changes: 28 additions & 0 deletions src/NHibernate.Test/Async/Linq/ParameterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,34 @@ public async Task UsingTwoEntityParametersAsync()
2));
}

[Test]
public async Task UsingEntityEnumerableParameterTwiceAsync()
{
if (!Dialect.SupportsSubSelects)
{
Assert.Ignore();
}

var enumerable = await (db.DynamicUsers.FirstAsync());
await (AssertTotalParametersAsync(
db.DynamicUsers.Where(o => o == enumerable && o != enumerable),
1));
}

[Test]
public async Task UsingEntityEnumerableListParameterTwiceAsync()
{
if (!Dialect.SupportsSubSelects)
{
Assert.Ignore();
}

var enumerable = new[] {await (db.DynamicUsers.FirstAsync())};
await (AssertTotalParametersAsync(
db.DynamicUsers.Where(o => enumerable.Contains(o) && enumerable.Contains(o)),
1));
}

[Test]
public async Task UsingValueTypeParameterTwiceAsync()
{
Expand Down
Loading