使用表达式在NHibernate QueryOver中进行动态排序
给出以下QueryOver
:
UserProfile userProfileAlias = null; Pegfile pegfileAlias = null; var q = Session.QueryOver(() => pegfileAlias) .JoinAlias(() => pegfileAlias.UserProfile, () => userProfileAlias);
我想通过交换使以下语句动态化
q = q.OrderBy(() => userProfileAlias.Forename).Asc;
(OrderBy(Expression<Func>
或( OrderBy(Expression<Func>)
)
同
q = q.OrderBy(GetMemberExpression(userProfileAlias, "Forename")).Asc;
我借了另一篇文章来获取
private Expression<Func> 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>(body); return lambda; }
但这不起作用,我得到:
System.InvalidOperationException No coercion operator is defined between types 'System.String' and 'Pegfect.Domain.PegDudes.UserProfile'.
我想我可能需要匹配以下信号:
OrderBy(Expression<Func>)
如何将GetMemberExpression
转换为返回?
你的版本不起作用的原因是NHibernate实际上没有为在JoinAlias
用作别名的变量JoinAlias
。 它只是一个被解析的令牌。 这意味着当您想在其他地方使用它时,它需要是完全相同的变量 。
要实现此目的,您需要保存别名表达式并使用其正文来检索该变量:
UserProfile alias = null; Expression> aliasExpression = () => alias; session.QueryOver() .JoinAlias(x => x.UserProfiles, aliasExpression) .OrderBy(GetMemberExpression(aliasExpression, "Forename")).Asc .List(); private Expression> GetMemberExpression( Expression> aliasExpression, string property) { var propertyExpression = Expression.Property(aliasExpression.Body, typeof(UserProfile), property); var body = Expression.Convert(propertyExpression, typeof(object)); var result = Expression.Lambda>(body); return result; }