NHibernate:在主键上按示例查询产生“WHERE(1 = 1)”

时间:2009-01-08 15:39:30

标签: nhibernate

我有一个实体客户

public class Customer
{
    public virtual int ID { get; set; }
    public virtual string Firstname { get; set; }
    public virtual string Lastname { get; set; }
}

我的DAL方法是:

    public IList<Customer> GetCustomers(Customer example)
    {
        var customers = default(IList<Customer>);

        using (var sessiong = GetSession())
        {
            customers = sessiong.CreateCriteria(typeof(Customer))
                .Add(Example.Create(example))
                .List<Customer>();
        }

        return customers;
    }

但问题是当我像这样调用我的方法时

    var exemple = new Customer() { ID = 2 };
    var customers = provider.GetCustomers(exemple);

我拥有数据库中所有客户的集合,因为NHibernate会生成以下SQL查询

NHibernate: SELECT this_.CustomerId as CustomerId0_0_, this_.Firstname as Firstname0_0_, this_.Lastname as Lastname0_0_ FROM Customers this_ WHERE (1=1)

NHibernate在主键上支持QBE吗? 我究竟做错了什么 ?

P.S。我忘了提到我正在使用的NHibernate版本。这是2.0.1.GA。

3 个答案:

答案 0 :(得分:11)

“通过示例使用查询时将忽略ID。这样做是因为具有id设置的示例对象无论如何都只返回一个对象。” - http://forum.hibernate.org/viewtopic.php?t=927063http://forum.hibernate.org/viewtopic.php?p=2351666&sid=c22d2c37f8d67e268b6ffe547f57ad9e
这适用于Hibernate。 NHibernate从它移植过来。所以我确信这也是NHibernate的设计。所以在id上使用Get而不是QBE。

答案 1 :(得分:0)

如果您通过示例条件对象在查询上使用EnableLike()来查询主键的一部分+其他一些属性,那么您的查询将返回多于1条记录。例如:用户的用户名是主键。您的对象的属性(包括主键)设置为应由like运算符查询的值。在这种情况下,除了编写自己的查询方法外,NHibernate别无选择。

答案 2 :(得分:0)

我知道这是一篇旧帖子,但我今天遇到了这个问题,这里的答案都没有帮助。只要示例中未指定ID列,我们就有一个名为 CountByExample ()的方法可以正常工作。

对于我们的场景,只有具有指定ID的对象存在一组特定参数时,计数才有效。该对象是一个相当大的对象,因此加载它将是不必要的资源浪费和带宽。因为NHibernate从示例中剥离了ID,所以计数始终不正确。

我通过以下调整解决了这个问题,对我来说很合适。

            criteria.Add(example);
            //HACK: Check for ID query and force NHibernate to take it
            var prop = searchParameters.GetType().GetProperty("ID");
            if (prop != null)
            {
                criteria.Add(Restrictions.Eq("ID", prop.GetValue(exampleT)));
            }

其中“searchParameters”是一个像这样的对象:

var searchParameters= new { ID = 48, isEnabledForAds = true, hasOptedOut = false};