现数据库有三个表
-用户表
create table User
(
Id int identity(1,1),
Name varchar(50),
constraint [pk_user] primary key  clustered 
(
[Id]
) on [primary])
go-权限表
create table Role
(
Id int identity(1,1),
ame varchar(50),
constraint [pk_role] primary key  clustered 
(
[Id]
) on [primary]
)
go-关系表
create table UserRole
(
     UserId int , 
     RoleId int,
constraint [pk_role] primary key  clustered 
(
[UserId],
[RoleId]
) on [primary]
)
go
//省写了一些代码
public class User
{
public int Id{get;set;}

public string Name{get;set;}

public IList Roles{get;set;}
}//省写了一些代码
public class Role 
{
public int Id{get;set;}

public string Name{get;set;}

public IList Users{get;set;}
}//hbm 就些写了
现要做如下查询,用TSQL来写:
select u.* 
from UserRole ur 
inner join User u on ur.UserId = u.Id 
where u.Name like '%sss%' and ur.RoleId = 5
或者进行如下查询:
select u.* ,ur.Name
from UserRole ur 
inner join User u on ur.UserId = u.Id 
where u.Name like '%sss%' and ur.RoleId = 5
HQL,应该如何写呢?
对应的hbm

解决方案 »

  1.   

    你没写.hbm.xml文件吗?
    下面是一个网上的例子,看着可能比较长,相信你如果全部按着做下来的话,应该没有什么太大问题的,
    不明白的问.
    NHibernate简介2006-12-23 17:42什么是NHibernate?
    NHibernate是一个基于.Net,用于关系数据库的对象持久化类库.它是著名的Hibernate的.Net版本.
    NHibernate用于把你的.Net对象持久化到底层的关系数据库中.你完全不用自己编写Sql语句去操作这些对象,NH会代替你做.你的代码里面只需要关心这些对象,NH生成sql语句并能为你取到正确的东西.
    开发过程
    HNibernate将会有一些工具帮助你,如:生成schema,根据映射文件(Mapping file)生成类,并更新schema(一个新开发者的建议).然而,在本文档中,前提是你已经手动的数据库的创建喝.Net类的编写...
    这里是我们要做的:
     
    1.       在数据库中创建把.Net类持久化的对应表.
    2.       创建需要被持久化的.Net类.
    3.       创建映射文件,以告诉NH怎样持久化这些类的属性.
    4.       创建NH的配置文件,以告诉NH怎样连接数据库.
    5.       使用NH提供的API.
     
    步骤1:创建数据库表
    我们正在做的是一个非常简单的NH示例.在这个例子里面,我们实现一个基本的用户管理子系统.我们将会使用一个user表(sql server 2000):
     
    use NHibernate
    go
     
    CREATE TABLE users (
      LogonID varchar(20) NOT NULL default '0',
      Name varchar(40) default NULL,
      Password varchar(20) default NULL,
      EmailAddress varchar(40) default NULL,
      LastLogon datetime default NULL,
      PRIMARY KEY  (LogonID)
    )
    go
     
    我使用的是MS Sql Server 2000,但是如果你找到一个任何数据库的.net Data Provider驱动,你可以使用任何数据库.
     
    步骤2:创建.Net类:
    当我们这样一堆的用户的时候,我们需要某种对象来保存.NH是通过reflection对象的属性来工作的,所以我们给需要持久化的对象添加属性.一个对应于上面数据库结构的类可以写成这个样子:
     
    using System;
     
    namespace NHibernate.Demo.QuickStart
    {
           public class User
           {
                  private string id;
                  private string userName;
                  private string password;
                  private string emailAddress;
                  private DateTime lastLogon;
     
     
                  public User()
                  {
                  }
     
                  public string Id 
                  {
                         get { return id; }
                         set { id = value; }
                  }
     
                  public string UserName 
                  {
                         get { return userName; }
                         set { userName = value; }
                  }
     
                  public string Password 
                  {
                         get { return password; }
                         set { password = value; }
                  }
     
                  public string EmailAddress 
                  {
                         get { return emailAddress; }
                         set { emailAddress = value; }
                  }
     
                  public DateTime LastLogon 
                  {
                         get { return lastLogon; }
                         set { lastLogon = value; }
                  }
                  
           }
    }
     
    在上面的代码里面,我们把属性和构造函数写成了public-NH并不要求一定要这样做.你可以使用public,protected,internal或者干脆private来标记你的属性.
     
     
    步骤3:编写映射文件(Mapping File)
    现在我们有了数据库表和.Net类,我们还需要告诉NH怎样在数据库和类之间映射.这就需要映射文件了.最简捷(也是可维护性最好的)方法就是为每一个类编写一个映射文件,如果你把命名为"XXX.hbm.xml"的映射文件和XXX类文件放在同一目录下,NH会很让 一切变得很轻松.这儿,我们的User.hbm.xml可能会像这样:
    <?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
        <class name="NHibernate.Demo.QuickStart.User, NHibernate.Demo.QuickStart" table="users">              <id name="Id" column="LogonId" type="String(20)">                     <generator class="assigned" />              </id>              <property name="UserName" column="Name" type="String(40)"/>              <property name="Password" type="String(20)"/>              <property name="EmailAddress" type="String(40)"/>              <property name="LastLogon" type="DateTime"/>       </class></hibernate-mapping>
      

  2.   


    让我们来看看这个有趣的映射文件:第一个tag是class,这里我们把类型名(类名和Assembly名)映射到数据库中的user表(这里和hibernate有些不同,我们必须告诉NH这个类从哪儿来的.这个差异是由.Net和Java Reflect机制的不同引起的-zyyang).这种情况下,我们是从Assembly NHibernate.Demo.QuickStart中载入NHibernate.Demo.QuickStart.User类..NH遵守.Net Framework使用Reflection载入类型的规则-所以遇到什么疑惑,就去查查.NET Framework SDK. 
    让我们暂时跳过"id" tag,先说property节点."name"属性值就是我们写的.Net类中的属性,column属性值就是在数据库中与'Net类属性对应的字段名.type属性是可选的(如果你没有标明,NH会给出一个最适合的),但是推荐的做法是带上这个属性.hibernate用户会注意到,在type属性值里,我们给出了长度值,这是因为ADO.NET需要这样做.
    让我们返回到"id" tag,你可能会猜想这个tag和映射到表的Primary Key有关.正确.ID  tag的格式和Property tag的相似.我们从Property(name)映射到目标数据库的字段(colume).
    这些嵌入的Generator标记告诉NH怎样生成Primary Key(NH很方便的就能给你生成一个,不管是什么类型的,只要你告诉它怎样去做).在我们举的例子中,把它设置成"assigned",意思是"我们的对象将自己生成key"(User对象将总是需要一个UserID),如果你乐意让NH代替你生成,你会对uuid.hex和uuid.string类感兴趣的(参看chm文档).
    Tip:如果你使用vs.net编译,设置Build Action,把User.hbm.xml文件作为资源绑定到Asssembly,这样映射文件就成了Asssembly的一部分了.后面我们会明白这个步骤的重要性.
     
    步骤4:创建数据库配置文件
    目前为止,我们还没有告诉NH到哪儿去找数据库.最直接的方法就是在你程序的配置文件中给NH一个部分,就是这样:
    <?xml version="1.0" encoding="utf-8" ?><configuration>     <configSections>               <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />       </configSections>       <nhibernate>              <add key="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider" />              <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />              <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />              <add key="hibernate.connection.connection_string" value="Server=localhost;initial catalog=nhibernate;User ID=someuser;Password=somepwd;Min Pool Size=2" />       </nhibernate></configuration>
    上面的例子中使用SqlClient驱动,连接到本地的nhibernate数据库,并且使用提供的用户和密码.还会有其他的配置项,你可以参看文档.
     
    步骤5:开始体验NHibernate的神奇
    所有艰苦的工作已经做完了.如果所有的工作完成后,你将会有这些成果:
    ?         User.cs - 需要持久化的.Net类.
    ?         User.hbm.xml - 映射文件
    ?         app.config - 带有Ado.net连接信息的配置文件(你也可以在代码中指定的)
    ?         一个叫做user的数据库表.
     
    在代码里面使用NHibernate是很简单的事情:
    1.       创建一个Configuration对象.
    2.       告诉Configuration你想要持久化哪一种对象.
    3.       创建一个Session连接到你设定的数据库.
    4.       载入,保存和查询你的对象.
    5.       Flush()你的Session
     
    好,让我们来看看一些代码:
     
    创建一个Configuration对象....
    Configuration对象知道所有在.Net类和后端数据库之间的映射关系,
     
    Configuration cfg = new Configuration();
    cfg.AddAssembly("NHibernate.Demo.QuickStart");
     
    Configuration对象会查找这个Assembly中所有以.hbm.xml结尾的文件.也有其他的方法添加映射文件,这个可能是最简单的一个.
     
    创建一个Session对象.......
    ISession对象代表着一个到后端数据库连接,ITransaction代表一个NHibernate管理的事务(Transaction).
     
    ISessionFactory factory = cfg.BuildSessionFactory();
    ISession session = factory.OpenSession();
    ITransaction transaction = session.BeginTransaction();
     
    载入,保存和查询你的对象......
     
    现在你可以以.net的方式对待这些对象.想在数据库中保存一个新的user?只需要:
     
    User newUser = new User();
    newUser.Id = "joe_cool";
    newUser.UserName = "Joseph Cool";
    newUser.Password = "abc123";
    newUser.EmailAddress = "[email protected]";
    newUser.LastLogon = DateTime.Now;
                  
    // Tell NHibernate that this object should be saved
    session.Save(newUser);
     
    // commit all of the changes to the DB and close the ISession
    transaction.Commit();
    session.Close();
     
    这就是NH的好处,大部分时间内你只用关心你的业务对象(BO).
     
    假如你需要根据已经知道的user ID查询一个对象,如果session是open的,你只需要一行:
     
    // open another session to retrieve the just inserted user
    session = factory.OpenSession();
    User joeCool = (User)session.Load(typeof(User), "joe_cool");
     
    这样你又会得到这个对象,设置一下对象的属性,它会在下一次Flush()方法出现的时候被持久化到数据库.
     
    // set Joe Cool's Last Login property
    joeCool.LastLogon = DateTime.Now;
     
    // flush the changes from the Session to the Database
    session.Flush();
     
    让NH去写入你对对象作出的修改,你只需要Flush Session就可以了.
     
    更好的是,你可以从数据库中查询到一个System.Collections.IList:
     
    IList userList = session.CreateCriteria(typeof(User)).List();
    foreach(User user in userList)
    {
           Console.WriteLine(user.Id + " last logged in at " + user.LastLogon);
    }
     
    这个查询会返回整个表的内容.尤其是当你想要更多的控制时候--像类出所有在March 14, 2004 10:00 PM之后登陆过的用户,你可以:
     
    IList recentUsers = session.CreateCriteria(typeof(User)).Add(Expression.Gt("LastLogon", new DateTime(2004, 03, 14, 20, 0, 0))).List();
    foreach(User user in recentUsers)
    {
           Console.WriteLine(user.Id + " last logged in at " + user.LastLogon);
    }
     
    文档里还有很多的查询选项,但是以上这些足够让你看出Hinernate的力量了.
    不要忘记了,最后要关掉你的Session.
     
    // tell NHibernate to close this Session
    session.Close();
      

  3.   

    NHiberante 是一个ORM工具,
    如果你用结构化的方法去用ORM,那么你还不如直接使用Duwamish的结构。你要用NH,
    Use就是是一个对象,Role也是一个对象,
    那么Use 和ROLE是什么关系,可以用依照对象关系在类中实现出来,比如,USE 和 ROLE是一个一对多的关系,
    那么,相应的HBM又是不一样的,
    而如果USE 和ROLE是一对一的关系。
    那么相应的HBM文件又是不一样的,
    这些都会有不同的HQL查询语句。。NHibernate是从JAVA的转过来的,参考手册是通用的,所以你可以参考Hibernate的手册
      

  4.   

    现在User 和 Role 是多对多的关系,要是一对多的,HQL我也是知道如何写的还是,HBM是多对多关系,我也配置好了。 我的问题是:
    如果用HQL,都得有对象
    但是我没有生成 UserRole这样的对象(因为这是一个纯关系表)。
      

  5.   

    如果Use Role是多对多的关系,
    你就必须将他们分解成一对多的关系,,,
      

  6.   

    谢谢兄弟们帮忙,尤其是:jonescheng(小块头无大智慧) 我已经改多对多关系为一对多关系,并用约束进行检查.
      

  7.   

    -用户表
    create table User
    (
    Id int identity(1,1),
    Name varchar(50),
    constraint [pk_user] primary key  clustered 
    (
    [Id]
    ) on [primary])
    go-权限表
    create table Role
    (
    Id int identity(1,1),
    ame varchar(50),
    constraint [pk_role] primary key  clustered 
    (
    [Id]
    ) on [primary]
    )
    go-关系表
    create table UserRole
    (
     Id int,
         UserId int , 
         RoleId int,
    constraint [pk_userrole] primary key  clustered 
    (
    [Id],
    ) on [primary],
    constraint [ix_userrole] unique  nonclustered 
    (
    [userid],
    [roleid]
    )  on [primary] 
    )
    go
    //省写了一些代码
    public class User
    {
    public int Id{get;set;}public string Name{get;set;}public IList Roles{get;set;}
    }//省写了一些代码
    public class Role 
    {
    public int Id{get;set;}public string Name{get;set;}public IList Users{get;set;}
    }//hbm 就些写了
    现要做如下查询,用TSQL来写:
    select u.* 
    from UserRole ur 
    inner join User u on ur.UserId = u.Id 
    where u.Name like '%sss%' and ur.RoleId = 5
    或者进行如下查询:
    select u.* ,r.Name
    from UserRole ur 
    inner join User u on ur.UserId = u.Id 
    inner join Role r on ur.RoleId = r.Id
    where u.Name like '%sss%' and ur.RoleId = 5对应的HQL如下:select ur.User from UserRole ur where ur.User.Name like '%sss%' and ur.Role = :role

    select ur.User, ur.Role.Name from UserRole ur where ur.User.Name like '%sss%' and ur.Role = :role