我正在使用: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版本?
答案 0 :(得分:5)
问题是由我声明的另一个映射引起的。我有一个继承自Client的类,它有一个关联的映射。这就是导致NHibernate查询两次的原因。我注意到了这一点,因为当使用Linq()时它返回了子类,而不是Client本身。这个特殊的继承和映射实例是我的设计缺陷,也是整个问题的根源!
答案 1 :(得分:1)
NHibernate与SQL Express没有任何问题,我已经相当广泛地使用它了。类似地,Fluent NHibernate不太可能在这个简单的场景中生成无效映射(但并非闻所未闻)。
在黑暗中拍摄,但我相信NHibernate保留名称Id作为标识符名称,因此当它在查询中看到Id时,它知道只看外键而不是实际连接的实体。也许你的ID命名而不是Id正在抛弃它?
答案 2 :(得分:1)
您可以尝试使用优秀的NHibernate分析器来更详细地了解正在发生的事情。它附带一个30天的试用许可证,而在Beta版中则有完整许可证费用的折扣