NHibernate连续两次记录并执行查询

时间:2009-03-10 05:46:14

标签: nhibernate fluent-nhibernate

我正在使用:SQL Server Express 2008上的NHibernate,NHibernate.Linq和Fluent NHibernate。我在引用属性上使用谓词选择一个实体(多个映射)。我有fetch = join,unique = true,lazy-load = false。我启用了log4net日志,当执行任何此类查询时,它会记录两个相同的SQL查询。运行查询返回一行,当我尝试使用IQueryable.Single扩展方法时,它会抛出异常,表明返回了多行。我也尝试使用标准的IQuery.UniqueResult方法运行查询,结果相同,它最终记录并实际运行查询两次,然后抛出一个异常,说明有多行,但是在管理工作室中运行实际查询只返回一个结果。当我禁用日志记录时,我收到相同的错误。

实体和映射声明如下(隐含了适当的访问修饰符和成员类型方差)

class User
{
    int ID;
    string UserName;
}

class Client
{
    int ID;
    User User;
    Person Person;
    Address Address;
}

class UserMap : ClassMap<User>
{
    public UserMap()
    {
       Id(x => x.ID);
       Map(x => x.UserName);
    }
}

class ClientMap : ClassMap<Client>
{
    public ClientMap()
    {
       Id(x => x.ID);
       References(x => x.User).Unique();
       ...
    }
}

然后我调用如下的查询:

ISession s = GetNHibernateSession();

...

var client = s.Linq<Client>().SingleOrDefault(x => x.User.ID = 17);

or

var client = s.Linq<Client>().Where(x => x.User.ID = 17);

or

var client = s.CreateQuery("from Client as c where c.User.ID = 17").UniqueResult<Client>();

在所有情况下执行两个相同的查询。当我启用延迟加载时,使用两个查询再次加载客户端,但是在访问成员(例如Person)时,只执行一个附加查询。

这可能是Fluent产生不正确映射的结果吗?或者NHibernate没有正确使用SQL Server Express版本?

3 个答案:

答案 0 :(得分:5)

问题是由我声明的另一个映射引起的。我有一个继承自Client的类,它有一个关联的映射。这就是导致NHibernate查询两次的原因。我注意到了这一点,因为当使用Linq()时它返回了子类,而不是Client本身。这个特殊的继承和映射实例是我的设计缺陷,也是整个问题的根源!

答案 1 :(得分:1)

NHibernate与SQL Express没有任何问题,我已经相当广泛地使用它了。类似地,Fluent NHibernate不太可能在这个简单的场景中生成无效映射(但并非闻所未闻)。

在黑暗中拍摄,但我相信NHibernate保留名称Id作为标识符名称,因此当它在查询中看到Id时,它知道只看外键而不是实际连接的实体。也许你的ID命名而不是Id正在抛弃它?

答案 2 :(得分:1)

您可以尝试使用优秀的NHibernate分析器来更详细地了解正在发生的事情。它附带一个30天的试用许可证,而在Beta版中则有完整许可证费用的折扣