NHibernate与LINQ,运算符“ ==”生成OR为“ is null”

时间:2018-09-26 12:44:38

标签: c# linq nhibernate orm

当我执行此查询时:

var query = from entity in session.Query<Entity>()
            where entity.Status != 2
            select entity;

NHibernate生成此SQL:

SELECT ...
FROM TABLE_NAME ALIAS
WHERE ALIAS.SITFIL <> 2 
       or ALIAS.SITFIL is null /*this 'or' is the problem*/

NHibernate为什么要这样做?

编辑:“或”导致我的应用程序出现性能问题

我只想生成:

SELECT ...
FROM TABLE_NAME ALIAS
WHERE ALIAS.SITFIL <> 2 

没有“或字段为空”

映射不能为空:

[Property(Column = "SITFIL", NotNull = true)]
public virtual TypeEnumOfProperty Status { get; set; }

枚举:

public enum TypeEnumOfProperty
{
    [Display(Name = "Ativa", Description ="Ativo")]
    Ativa = 0,
    [Display(Name = "Inativa", Description = "Inativo")]
    Inativa = 1,
    [Display(Name = "Inativa e oculta", Description = "Inativo e oculto")]
    InativaOculta = 2,
}

编辑:如果我将TypeEnumOfProperty更改为int,则生成SQL的方式如我所愿,如果更改为TypeEnumOfProperty或将其更改为long,则使用'or'生成。

如果在比较中使用“等于”,则NHibernate生成不带“或”的where子句。

有人知道为什么以及如何解决吗?

3 个答案:

答案 0 :(得分:1)

它正在执行您查询的内容,即

var query = from entity in session.Query<Entity>()
        where entity.Status != 2
        select entity;

返回所有内容,但不等于2。 因此,如果您不需要null,请改进查询。

var query = from entity in session.Query<Entity>()
            where entity.Status != 2 && entity.Status != null
            select entity;

总是更加安全,谁知道会破坏您的逻辑。

答案 1 :(得分:0)

这是默认行为。它本身不是错误,但是可以改进。

您可以通过以下方法解决此问题:

var query = from entity in session.Query<Entity>()
            where !(entity.Status == 2)
            select entity;

执行计划将与您的目标相同。您甚至可以插入一个自定义查询提供程序,该程序将自动为您重写所有这些内容。

答案 2 :(得分:0)

我认为您可以:

1)看到此article以在hbm.xml映射文件中设置枚举

     <property name="Status"  type="YourNamespace.Enums.TypeEnumOfProperty, YourNamespace.Enums"/>

2)在linq中使用equals优于==