使用 Nhibernate 按未映射的计算属性进行排序

本文关键字:属性 排序 计算 Nhibernate 映射 使用 | 更新日期: 2023-09-27 18:36:20

我有这些类:

public class Employee
{
    public virtual int Id { get; set; }
    public virtual decimal Salary { get; set; }
    public virtual decimal Tax { get; set; }
    public virtual decimal NetSalary { get { return Salary * (1 - Tax); } }
}

public class EmployeeMap : ClassMap<Employee>
{
    WithTable("Employees");
    Id(x => x.Id);
    Map(x => x.Salary);
    Map(x => x.Tax);
}

我正在从数据库中检索员工,如下所示:

var criteria = DetachedCriteria.For<Employee>();
criteria = criteria.AddOrder(Order.Asc(sortProperty)); // sortProperty is a string

现在,如果我想按Salary排序,但这很有效,但我想按NetSalary排序。我将如何实现这一目标?我无法更改数据库。我发现Order.Asc()超载需要投影。我确定我必须在该标准中创建一个投影并将其提供给那里,但我没有找到有关如何执行此操作的信息。

使用 Nhibernate 按未映射的计算属性进行排序

尽管不是最干净的方法,但您可以为计算属性定义投影,如下所示:

var netSalaryProjection = Projections.SqlProjection("Salary * (1 - Tax) as NetSalary", new[] { "NetSalary" }, new IType[] { NHibernateUtil.Decimal});

并使用它进行排序:

criteria.AddOrder(Order.Asc(netSalaryProjection));

请注意,这可能适用于 SQL Server 和可能的其他提供程序。

您是否考虑过存储计算值?这将需要将计算逻辑移动到资源库并添加用于存储的列。在读取时对数据进行排序时,它将执行更好的性能,因为计算是在写入期间执行的。这也将使按查询排序变得简单。希望这有帮助。