Limit collection retrieves only recent read-only records
A custom object can have thousands of UserOperations. Sometimes I don't want to fetch (for a readonly entity) all of them, but only "last 10 or not completed".
public class SimpleForm
{
public class User : EntityBase
{
// ...
private ISet<UserOperation> _recentOperations = new HashedSet<UserOperation>();
public virtual ISet<UserOperation> RecentOperations { get { return _recentOperations; } set { _recentOperations = value; } }
}
}
So how can I specify it? I think I can use display overrides?
I understand that I can do this with a separate request, but can this be done by mapping objects?
Also wondering if there is a way to make a part for a non-read object where I can change the collection of operations?
UPDATE
I tried to use
DateTime dateTime = (DateTime.UtcNow - TimeSpan.FromDays(15));
mapping.HasMany(x => x.RecentOperations)
.Where(x => x.EndedAt == null || x.EndedAt < dateTime);
but it says "Unable to convert expression to SQL".
I replaced it with
mapping.HasMany(x => x.RecentOperations)
.Where(x => x.EndedAt == null);
and now it throws a referenced link exception inside
at FluentNHibernate.Utils.ExpressionToSql.Convert (object value) at FluentNHibernate.Utils.ExpressionToSql.Convert (ConstantExpression) at FluentNHibernate.Utils.ExpressionToSql.Convert [T] (Expression`1, UnaryExpression body)
source to share
There are two main ways to filter the displayed collections.
The first bit is hard, fixed, in the definition defined in where=""
:
- 6.2. Collection matching (... freely
.Where(bool expr)
or.Where(Sql statement string)
The second, and perhaps really appropriate in this scenario, is a dynamic version called filter:
NHibernate adds the ability to pre-define filter criteria and attach those filters to both a class and a collection. Filter criteria is the ability to define a constraint clause very similar to the existing "where" attribute available on a class and various collection members. In addition, these filter parameters can be parameterized. The application can then decide at runtime whether filters should be allowed and what their parameter values should be. Filters can be used as database views, but are parameterized within the application ....
The getaway implementation would look like this:
public class RecentFilter : FilterDefinition
{
public RecentFilter()
{
WithName("RecentFilter")
.WithCondition("( :EndedAtDate IS NULL OR EndedAt < :EndedAtDate )")
.AddParameter("EndedAtDate",NHibernate.NHibernateUtil.DateTime);
}
}
this is a filter, and here is its use in free display:
mapping
.HasMany(x => x.RecentOperations)
...
.ApplyFilter<RecentFilter>();
At runtime, we can turn on / off the filter at the ISession level:
session.EnableFilter("RecentFilter")
.SetParameter("EndedAtDate",DateTime.Now.AddDays(-15));
See also:
source to share