nHibernate失败,没有where限制,但没有where限制

问题描述 投票:0回答:1

我目前正在使用NHibernate的C#项目中工作。在项目中,我们有一个名为“ Auftrag”的表,其中我只需要一些列。

仅选择我需要的列,我使用此代码:

ProjectionList projectionListSubTypeAuftrag = Projections.ProjectionList();
projectionListSubTypeAuftrag
    .Add(Projections.Property("AuftragID"), "Id")
    .Add(Projections.Property("Status"), "Status")
    .Add(Projections.Property("Typ"), "Typ");

DetachedCriteria auftragCriteria = DetachedCriteria.For(typeof(Auftrag));

auftragCriteria.SetProjection(projectionListSubTypeAuftrag);
auftragCriteria.SetResultTransformer(Transformers.AliasToBean(typeof(SubTypeAuftrag)));

IList<SubTypeAuftrag> auftragSubview;

using (ITransaction tx = session.BeginTransaction())
{
    auftragSubview = auftragCriteria.GetExecutableCriteria(session).List<SubTypeAuftrag>();

    tx.Commit();
}

这可以正常工作,并返回表中的所有行。现在,我要过滤条件:Status != 'A'

我试图通过以下代码实现这一点

auftragCriteria.Add(Restrictions.Not(Restrictions.Eq("Status", 'A')));

如果现在运行代码,我会收到异常:

System.Data.SqlClient.SqlException:创建或更改表“ FakeWorkTable”失败,因为最小行大小为16017,包括4个字节的内部开销。这超过了最大值允许的表行大小为8094字节。

当我查看生成的SQL语句时,一切看起来都很正常,我也可以在Microsoft SSMS中运行它。

现在我不了解的部分是,当我将auftragCriteria.Add(Restrictions.Not(Restrictions.Eq("Status", 'A')));更改为auftragCriteria.Add(Restrictions.Eq("Status", 'A'));时,一切正常。

我想念什么?

我找到了解决方法:

auftragCriteria.Add(Expression.Sql("Status <> 'A'"));

作品。

如果使用auftragCriteria.Add(Restrictions.Not(Restrictions.Eq("Status", 'A')));,则会得到此SQL查询

SELECT this_.auftragid as y0_,
       this_.status    as y1_,
       this_.typ       as y2_
FROM   auftrag this_
WHERE  not (this_.status = 'A' /* @p0 */)

如果我使用auftragCriteria.Add(Expression.Sql("Status <> 'A'"));,我会得到这个:

SELECT this_.auftragid as y0_,
       this_.status    as y1_,
       this_.typ       as y2_
FROM   auftrag this_
WHERE  Status <> 'A'

他们的行为不一样吗?

c# sql-server nhibernate nhibernate-mapping
1个回答
0
投票

据我从查看NHibernate源代码可以看出的,使用Restrictions.Not(Restrictions.Eq("Status", 'A'))似乎是实现“不等于”运算符的正确方法。在Java版本的Hibernate中,有Restrictions.ne被转换为'<>'运算符。

我要检查的几件事。使用最新的NHibernate版本运行代码,然后查看问题是否仍然存在。从错误消息来看,我怀疑您在此处显示的代码中还有更多的事情发生。尝试用可能的最少代码来复制问题。

[我认为比使用Expression.Sql更好的另一种解决方法是将LtGtOr一起使用:

auftragCriteria.Add(
    Restrictions.Or(
        Restrictions.Lt("Status", 'A'), 
        Restrictions.Gt("Status", 'A')));

应该成为:

WHERE (this_.status < 'A' or this.status > 'A')
© www.soinside.com 2019 - 2024. All rights reserved.