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

Posted

技术标签:

【中文标题】使用 Nhibernate 按未映射的计算属性进行排序【英文标题】:Use Nhibernate to sort by a calculated property that's not mapped 【发布时间】:2015-01-06 12:18:33 【问题描述】:

我有这些课程:

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() 的过载会导致投影。我确定我必须在该标准中创建一个投影并将其提供给那里,但我没有找到有关如何执行此操作的信息。

【问题讨论】:

【参考方案1】:

虽然不是最简洁的方法,但您可以为计算的属性定义投影,如下所示:

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

并将其用于排序:

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

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

【讨论】:

请注意(至少在我使用的 NHibernate 版本上)SQL 片段中的 AS 子句是绝对必要的,否则整个字符串将被截断为空。【参考方案2】:

您是否考虑过存储计算值?这将需要将计算逻辑移动到设置器并添加一列进行存储。由于计算是在写入期间执行的,因此在读取时对数据进行排序时性能会更好。这也将使查询的顺序变得简单。希望这可以帮助。

【讨论】:

以上是关于使用 Nhibernate 按未映射的计算属性进行排序的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate:映射具有属性的复杂值类型?

如何使用 NHibernate 联合子类映射抽象属性?

通过 NHibernate 代码映射将 GUID 属性作为外键映射到其他实体

NHibernate 将 1 个对象映射到 2 个表

使用自动映射时如何使用 Fluent NHibernate Validator?

nHibernate:如何映射可以是任何类型的属性?