代码之家  ›  专栏  ›  技术社区  ›  eulerfx

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

  •  3
  • eulerfx  · 技术社区  · 16 年前

    我在SQL Server Express 2008上使用:nhibernate、nhibernate.linq和fluent nhibernate。我正在使用引用属性(多个映射)上的谓词选择实体。我有fetch=join、unique=true、lazy load=false。我启用了log4net日志,当任何这样的查询执行时,它会记录两个相同的SQL查询。运行查询将返回一行,当我尝试使用iQueryable.Single扩展方法时,它将引发异常,说明返回了多行。我还尝试使用具有相同结果的标准i query.uniqueresult方法运行查询,结果是记录并实际运行查询两次,然后引发异常,说明有多行,但是在Management Studio中运行实际查询只返回一个结果。当我禁用日志记录时,我会收到相同的错误。

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

    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>();
    

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

    这可能是Fluent生成不正确映射的结果吗?或者SQL Server Express Edition未被nhibernate正确使用?

    3 回复  |  直到 16 年前
        1
  •  5
  •   eulerfx    16 年前

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

        2
  •  1
  •   James Gregory    16 年前

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

    在黑暗中拍摄,但我相信nhibernate保留名称ID作为标识符名称,所以当它在查询中看到ID时,它知道只查看外键而不是实际连接的实体。也许你用ID而不是ID来命名是为了扔掉它?

        3
  •  1
  •   Keith Bloom    16 年前

    你可以试着用优秀的 NHibernate 事件探查器查看正在发生的事情的更详细的视图。它附带30天试用许可证,而在试用版中,完全许可证成本有折扣。