问题
Given the following QueryOver
:
UserProfile userProfileAlias = null;
Pegfile pegfileAlias = null;
var q = Session.QueryOver(() => pegfileAlias)
.JoinAlias(() => pegfileAlias.UserProfile, () => userProfileAlias);
I would like to make the following statement dynamic, by swapping
q = q.OrderBy(() => userProfileAlias.Forename).Asc;
(OrderBy(Expression<Func<object>>
or (OrderBy(Expression<Func<T, object>>)
)
with
q = q.OrderBy(GetMemberExpression(userProfileAlias, "Forename")).Asc;
I borrowed from another post to get
private Expression<Func<object>> GetMemberExpression(UserProfile instance, string propertyName)
{
var arg = Expression.Constant(instance, typeof(UserProfile));
var body = Expression.Convert(Expression.PropertyOrField(arg, propertyName), typeof(UserProfile));
var lambda = Expression.Lambda<Func<object>>(body);
return lambda;
}
but this isn't working, i get:
System.InvalidOperationException
No coercion operator is defined between types 'System.String' and 'Pegfect.Domain.PegDudes.UserProfile'.
i think I probably need to match the following sig:
OrderBy(Expression<Func<UserProfile,object>>)
how to turn GetMemberExpression
into returning that?
回答1:
The reason why your version doesn't work is the fact that NHibernate doesn't actually assign a value to the variable used as an alias in JoinAlias
. It is merely a token that is being parsed. This means that it needs to be the exact same variable, when you want to use it elsewhere.
To achieve this, you need to save the alias expression and use its body to retrieve that variable:
UserProfile alias = null;
Expression<Func<object>> aliasExpression = () => alias;
session.QueryOver<Pegfile>()
.JoinAlias(x => x.UserProfiles, aliasExpression)
.OrderBy(GetMemberExpression(aliasExpression, "Forename")).Asc
.List();
private Expression<Func<object>> GetMemberExpression(
Expression<Func<object>> aliasExpression,
string property)
{
var propertyExpression = Expression.Property(aliasExpression.Body,
typeof(UserProfile), property);
var body = Expression.Convert(propertyExpression, typeof(object));
var result = Expression.Lambda<Func<object>>(body);
return result;
}
来源:https://stackoverflow.com/questions/14319092/dynamic-sorting-in-nhibernate-queryover-using-expressions