3

我在 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 版本?

4

3 回答 3

5

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

于 2009-03-11T23:49:49.883 回答
1

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

在黑暗中开枪,但我相信 NHibernate 将名称 Id 保留为标识符名称,因此当它在查询中看到 Id 时,它知道只查看外键而不是实际连接的实体。也许您对 ID 而不是 Id 的命名是把它扔掉了?

于 2009-03-11T08:58:43.737 回答
1

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

于 2009-03-11T09:24:41.553 回答